Exemple #1
0
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')
        ])
Exemple #2
0
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()))
    ])
Exemple #5
0
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')])
Exemple #6
0
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')
                                                 ])]])
Exemple #8
0
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')
        ],
    )
Exemple #9
0
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())))
Exemple #10
0
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'}
                                                )['&times']]],
                                                _.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'
        ])