def card(node: pipelines.Node) -> str: """A card that shows the system stats, the time line and output for the last runs or a node""" return bootstrap.card( id='last-runs-card', header_left=[ 'Last runs ', _.div(style='display:inline-block;margin-left:20px;')[ html.asynchronous_content( flask.url_for('mara_pipelines.last_runs_selector', path=node.url_path()))] ], body=[ html.spinner_js_function(), html.asynchronous_content(url=flask.url_for( 'mara_pipelines.system_stats', path=node.url_path(), run_id=None), div_id='system-stats'), html.asynchronous_content(url=flask.url_for( 'mara_pipelines.timeline_chart', path=node.url_path(), run_id=None), div_id='timeline-chart'), html.asynchronous_content(url=flask.url_for( 'mara_pipelines.run_output', path=node.url_path(), run_id=None, limit=True), div_id='run-output') ])
def index_page() -> response.Response: """Renders the overview page""" from ..config import data_sets return response.Response(html=[ bootstrap.card(header_left='Entities & their relations', body=html.asynchronous_content( flask.url_for('mara_schema.overview_graph'))), bootstrap.card( header_left='Data sets', body=bootstrap.table(['Name', 'Description'], [ _.tr[_.td[_.a( href=flask. url_for('mara_schema.data_set_page', id=data_set.id() ))[escape(data_set.name)]], _.td[_.i[escape(data_set.entity.description)]], ] for data_set in data_sets() ]), ) ], title='Data sets documentation', css_files=[ flask.url_for('mara_schema.static', filename='schema.css') ])
def __(pipeline: pipelines.Pipeline): return bootstrap.card( header_left='Nodes', header_right=[ bootstrap.button( id='run-with-upstreams-button', label='Run with upstreams', icon='play', url=flask.url_for('data_integration.run_page', path=pipeline.url_path(), with_upstreams=True), title= f'Run selected nodes with all their upstreams in pipeline "{pipeline.id}"' ), ' ', bootstrap.button(id='run-button', label='Run ', icon='play', url=flask.url_for('data_integration.run_page', path=pipeline.url_path(), with_upstreams=False), title='Run selected nodes') ] if config.allow_run_from_web_ui() else [], body=html.asynchronous_content( url=flask.url_for('data_integration.pipeline_children_table', path=pipeline.url_path())))
def card(node: pipelines.Pipeline): return bootstrap.card(body=[ _.p[_.em[node.description]], (_.p[views.format_labels(node)] if node.labels else ''), html.asynchronous_content( flask.url_for('data_integration.dependency_graph', path=node.url_path())) ])
def index_page(): return response.Response( html=[bootstrap.card( header_left=_.a(href=flask.url_for('mara_data_explorer.data_set_page', data_set_id=ds.id))[ds.name], body=[html.asynchronous_content(flask.url_for('mara_data_explorer.data_set_preview', data_set_id=ds.id))]) for i, ds in enumerate(config.data_sets())], title='Data sets', js_files=[flask.url_for('mara_data_explorer.static', filename='data-sets.js')], css_files=[flask.url_for('mara_data_explorer.static', filename='data-sets.css')])
def index_page(db_alias: str): """A page that visiualizes the schemas of a database""" if db_alias not in config.databases(): flask.abort(404, f'unkown database {db_alias}') return response.Response( title=f'Schema of database {db_alias}', html=[bootstrap.card(sections=[ html.asynchronous_content(flask.url_for('mara_db.schema_selection', db_alias=db_alias)), [_.div(id='schema-container')]]), html.spinner_js_function()], js_files=[flask.url_for('mara_db.static', filename='schema-page.js')], action_buttons=[response.ActionButton( action='javascript:schemaPage.downloadSvg()', label='SVG', title='Save current chart as SVG file', icon='download')] )
def start_page(): import mara_pipelines.config from mara_data_explorer.data_set import find_data_set data_set_for_preview = find_data_set('order_items') assert (data_set_for_preview) return response.Response( title='MyCompany BI', html=_.div(class_='row')[_.div( class_='col-lg-6' )[bootstrap. card(header_left=_.b['Welcome'], body=[ _. p['This is the first thing that users of your data warehouse will see. ', 'Please add links to relevant documentation, tutorials & other ', 'data tools in your organization.'], _.p[ _.a(href='https://github.com/mara/mara-example-project-1/blob/master/app/ui/start_page.py' )[ 'Here'], ' is the source code for this page, and here is a picture of a ', _.a(href='https://en.wikipedia.org/wiki/Mara_(mammal)' )[ 'mara'], ':'], _. img(src=flask.url_for('ui.static', filename='mara.jpg'), style ='width:40%; margin-left: auto; margin-right:auto; display:block;' ) ]), bootstrap.card(header_left=[ _.b[_.a(href=flask.url_for('mara_metabase.metabase'))[_.span( class_='fa fa-bar-chart')[''], ' Metabase']], ' & ', _. b[_.a(href=flask.url_for('mara_mondrian.saiku'))[_.span( class_='fa fa-bar-chart')[''], ' Saiku']], ': Company wide dashboards, pivoting & ad hoc analysis' ], body=[ _. p['Metabase tutorial: ', _. a(href= 'https://www.metabase.com/docs/latest/getting-started.html' ) ['https://www.metabase.com/docs/latest/getting-started.html']], _. p['Saiku introduction: ', _. a(href= 'https://saiku-documentation.readthedocs.io/en/latest/' ) ['https://saiku-documentation.readthedocs.io/en/latest/']] ]), bootstrap.card(header_left=[ _.b[_.a(href=flask.url_for('mara_data_explorer.index_page'))[ _.span(class_='fa fa-table')[''], ' Explore']], ': Raw data access & segmentation' ], body=[ _.p[_.a( href=flask. url_for('mara_data_explorer.data_set_page', data_set_id=data_set_for_preview.id ))[data_set_for_preview.name], ':', html.asynchronous_content( flask.url_for( 'mara_data_explorer.data_set_preview', data_set_id=data_set_for_preview.id) )], _. p['Other data sets: ', ', '.join([ str( _.a(href=flask.url_for( 'mara_data_explorer.data_set_page', data_set_id=ds.id))[ds.name]) for ds in mara_data_explorer.config.data_sets( ) if ds.id != data_set_for_preview.id ])] ])], _.div(class_='col-lg-6') [bootstrap. card(header_left=[ _.b[_.a(href=flask.url_for( 'mara_schema.index_page'))[_.span( class_='fa fa-book' )[''], ' Data sets']], ': Documentation of attributes and metrics of all data sets' ], body=html.asynchronous_content( url=flask. url_for('mara_schema.overview_graph' ))), bootstrap.card(header_left=[ _.b[_.a( href=flask. url_for('mara_pipelines.node_page') )[_.span(class_='fa fa-wrench')[''], ' Pipelines']], ': The data integration pipelines that create the DWH' ], body=html. asynchronous_content( flask.url_for( 'mara_pipelines.dependency_graph', path='/'))), bootstrap.card(header_left=[ _.b[_.a(href=flask. url_for('mara_db.index_page') )[_.span( class_='fa fa-database')[''], ' Database Schemas']], ': Schemas of all databases connections' ], body=[ html.asynchronous_content( flask.url_for( 'mara_db.draw_schema', db_alias= mara_pipelines. config. default_db_alias( ), schemas='ec_dim' ) + '?hide-columns=True') ])]])
def data_set_page(id: str) -> response.Response: """Renders the pages for individual data sets""" from ..config import data_sets data_set = next( (data_set for data_set in data_sets() if data_set.id() == id), None) if not data_set: flask.flash(f'Could not find data set "{id}"', category='warning') return flask.redirect(flask.url_for('mara_schema.index_page')) base_url = flask.url_for('mara_schema.data_set_sql_query', id=data_set.id()) def attribute_rows(data_set: DataSet) -> []: rows = [] for path, attributes in data_set.connected_attributes().items(): if path: rows.append(_.tr[_.td( colspan=3, style='border-top:none; padding-top: 20px;' )[[[ '→ ', _.a( href=data_set_url(entity.data_set) )[link_title] if entity.data_set else link_title, ' ' ] for entity, link_title in [( entity_link.target_entity, entity_link.prefix or entity_link.target_entity.name) for entity_link in path]], [' ', _. i[path[-1].description]] if path[-1].description else '']]) for prefixed_name, attribute in attributes.items(): rows.append(_.tr[_.td[escape(prefixed_name)], _.td[_.i[escape( attribute.description )]], _.td[_.tt[escape( f'{path[-1].target_entity.table_name + "." if path else ""}{attribute.column_name}' )]]]) return rows return response.Response( html=[ bootstrap.card( header_left=_.i[escape(data_set.entity.description)], body=[ _.p['Entity table: ', _.code[escape( f'{data_set.entity.schema_name}.{data_set.entity.table_name}' )]], html.asynchronous_content( flask.url_for('mara_schema.data_set_graph', id=data_set.id())), ]), bootstrap.card( header_left='Metrics', body=[ html.asynchronous_content( flask.url_for('mara_schema.metrics_graph', id=data_set.id())), bootstrap.table(['Name', 'Description', 'Computation'], [[ _.tr[_.td[escape(metric.name)], _.td[_.i[escape(metric.description)]], _.td[_.code[escape(metric.display_formula())]]] for metric in data_set.metrics.values() ]]), ]), bootstrap.card(header_left='Attributes', body=bootstrap.table( ["Name", "Description", "Column name"], attribute_rows(data_set))), bootstrap.card( header_left=[ 'Data set sql query: ', [ _.div(class_='form-check form-check-inline') [" ", _.label(class_='form-check-label')[ _.input(class_="form-check-input param-checkbox", type="checkbox", value=param)[''], ' ', param]] for param in [ 'human readable columns', 'pre-computed metrics', 'star schema', 'personal data', 'high cardinality attributes', ] ] ], body=[ _.div(id='sql-container')[html.asynchronous_content( base_url, 'sql-container')], _.script[''' document.addEventListener('DOMContentLoaded', function() { DataSetSqlQuery("''' + base_url + '''"); }); '''] ]) ], title=f'Data set "{data_set.name}"', js_files=[ flask.url_for('mara_schema.static', filename='data-set-sql-query.js') ], )
def card(node: pipelines.Node): """A card that shows the duration of the node and its top children over time""" return bootstrap.card(header_left='Run times', body=html.asynchronous_content( flask.url_for('mara_pipelines.run_time_chart', path=node.url_path())))
def view_plots(): return response.Response( html=[ _.div(id='forecast-container')[_.div(class_="")[[ [ _.div(class_='row')[_.div(class_='col-xl-12')[_.div( class_='section-header')[forecast.metric_name]]], _.div(class_='row')[_.div(class_='col-xl-12')[ _.p()['Number of days: ' + str(forecast.number_of_days), _.br(), 'Time-series query: ', html.highlight_syntax(forecast.time_series_query, language='postgresql')], bootstrap.card( header_left='Forecast plot of "' + forecast.metric_name + '"', header_right=_.div()[ # config.forecast_table_name # _.a(class_='query-control', style='margin-right: 10px', # href='#')[ # _.span(class_='fa fa-download')[' ']], _. a(class_='query-control', href=f"javascript:showQueryDetails('" f"{flask.url_for('forecasts.query_details', name=forecast.metric_name)}')" )[_.span(class_='fa fa-eye')[' ']]], body=[ html.asynchronous_content( flask.url_for('forecasts.get_plot_image', name=forecast.metric_name. lower().replace(' ', '_'). replace('-', '_'), components='False')), _.br(), _.br(), _.div(class_='modal fade', id='query-details-dialog', tabindex="-1" )[_.div(class_='modal-dialog modal-lg', role='document')[_.div( class_='modal-content' )[_.div( class_='modal-header' )[_.h5(class_='modal-title' )['Time-series query'], _.button( **{ 'type': "button", 'class': "close", 'data-dismiss': "modal", 'aria-label': "Close" } )[_.span( **{'aria-hidden': 'true'} )['×']]], _.div(class_='modal-body', id='query-details' )['']]]], ])], _. div(class_='col-xl-12')[bootstrap.card( header_left= 'Forecast components (trend, holidays, seasonality) of "{}"' .format(forecast.metric_name), header_right='', body=[ html.asynchronous_content( flask.url_for( 'forecasts.get_plot_image', name=forecast. metric_name.lower( ).replace(' ', '_'). replace('-', '_'), components='True')), ])], _.hr()] ] for forecast in config.forecasts() ]]], _.script[''''''] ], title='Forecasts', css_files=[ 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,700', flask.url_for('forecasts.static', filename='forecast.css') ], js_files=[ flask.url_for('forecasts.static', filename='forecast.js'), 'https://www.gstatic.com/charts/loader.js' ])