Ejemplo n.º 1
0
def test_render_DefaultJinjaPageView_meta_info():
    validation_results = {
        "results": [],
        "statistics": {
            "evaluated_expectations": 156,
            "successful_expectations": 139,
            "unsuccessful_expectations": 17,
            "success_percent": 89.1025641025641
        },
        "meta": {
            "great_expectations.__version__": "0.7.0-beta",
            "data_asset_name": "tetanusvaricella",
            "expectation_suite_name": "my_suite",
            "run_id": "2019-06-25T14:58:09.960521",
            "batch_kwargs": {
                "path":
                "/Users/user/project_data/public_healthcare_datasets/tetanusvaricella/tetvardata.csv",
                "timestamp": 1561474688.693565
            }
        }
    }

    document = RenderedDocumentContent(
        dict_to_ordered_dict(
            ProfilingResultsPageRenderer().render(validation_results)))
    html = DefaultJinjaPageView().render(document)
    with open(
            './tests/render/output/test_render_DefaultJinjaPageView_meta_info.html',
            'w') as outfile:
        outfile.write(html)
def test_render_section_page():
    section = RenderedSectionContent(
        **{
            "section_name": None,
            "content_blocks": [
                RenderedHeaderContent(
                    **{
                        "content_block_type": "header",
                        "header": "Overview",
                    }
                ),
                RenderedTableContent(
                    **{
                        "content_block_type": "table",
                        "header": "Dataset info",
                        "table": [
                            ["Number of variables", "12"],
                            ["Number of observations", "891"],
                        ],
                        "styling": {
                            "classes": ["col-6", "table-responsive"],
                            "styles": {"margin-top": "20px"},
                            "body": {"classes": ["table", "table-sm"]},
                        },
                    }
                ),
            ],
        }
    )

    rendered_doc = ge.render.view.view.DefaultMarkdownPageView().render(
        RenderedDocumentContent(sections=[section])
    )

    rendered_doc = rendered_doc.replace(" ", "").replace("\t", "").replace("\n", "")

    assert (
        rendered_doc
        == """
        #ValidationResults
        ##Overview
        ###Datasetinfo
        ||||------------|------------|Numberofvariables|12Numberofobservations|891
        -----------------------------------------------------------
        Poweredby[GreatExpectations](https://greatexpectations.io/)
        """.replace(
            " ", ""
        )
        .replace("\t", "")
        .replace("\n", "")
    )
Ejemplo n.º 3
0
    def render(self, expectations):
        if isinstance(expectations, dict):
            expectations = ExpectationSuite(**expectations, data_context=None)
        (
            columns,
            ordered_columns,
        ) = expectations.get_grouped_and_ordered_expectations_by_column()
        expectation_suite_name = expectations.expectation_suite_name

        overview_content_blocks = [
            self._render_expectation_suite_header(),
            self._render_expectation_suite_info(expectations),
        ]

        table_level_expectations_content_block = self._render_table_level_expectations(
            columns)
        if table_level_expectations_content_block is not None:
            overview_content_blocks.append(
                table_level_expectations_content_block)

        asset_notes_content_block = self._render_expectation_suite_notes(
            expectations)
        if asset_notes_content_block is not None:
            overview_content_blocks.append(asset_notes_content_block)

        sections = [
            RenderedSectionContent(
                **{
                    "section_name": "Overview",
                    "content_blocks": overview_content_blocks,
                })
        ]

        sections += [
            self._column_section_renderer.render(expectations=columns[column])
            for column in ordered_columns if column != "_nocolumn"
        ]
        return RenderedDocumentContent(
            **{
                "renderer_type": "ExpectationSuitePageRenderer",
                "page_title": f"Expectations / {str(expectation_suite_name)}",
                "expectation_suite_name": expectation_suite_name,
                "utm_medium": "expectation-suite-page",
                "sections": sections,
            })
Ejemplo n.º 4
0
    def render(self, validation_results):
        run_id = validation_results.meta["run_id"]
        if isinstance(run_id, str):
            try:
                run_time = parse(run_id).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
            except (ValueError, TypeError):
                run_time = "__none__"
            run_name = run_id
        elif isinstance(run_id, dict):
            run_name = run_id.get("run_name") or "__none__"
            run_time = run_id.get("run_time") or "__none__"
        elif isinstance(run_id, RunIdentifier):
            run_name = run_id.run_name or "__none__"
            run_time = run_id.run_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

        expectation_suite_name = validation_results.meta[
            "expectation_suite_name"]
        batch_kwargs = validation_results.meta.get(
            "batch_kwargs", {}) or validation_results.meta.get(
                "batch_spec", {})

        # add datasource key to batch_kwargs if missing
        if "datasource" not in batch_kwargs and "datasource" not in batch_kwargs:
            # check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern
            if len(expectation_suite_name.split(".")) == 4:
                if "batch_kwargs" in validation_results.meta:
                    batch_kwargs["datasource"] = expectation_suite_name.split(
                        ".")[0]
                else:
                    batch_kwargs["datasource"] = expectation_suite_name.split(
                        ".")[0]

        # Group EVRs by column
        # TODO: When we implement a ValidationResultSuite class, this method will move there.
        columns = self._group_evrs_by_column(validation_results)

        ordered_columns = Renderer._get_column_list_from_evrs(
            validation_results)
        column_types = self._overview_section_renderer._get_column_types(
            validation_results)

        data_asset_name = batch_kwargs.get("data_asset_name")
        # Determine whether we have a custom run_name
        try:
            run_name_as_time = parse(run_name)
        except ValueError:
            run_name_as_time = None
        try:
            run_time_datetime = parse(run_time)
        except ValueError:
            run_time_datetime = None

        include_run_name: bool = False
        if run_name_as_time != run_time_datetime and run_name_as_time != "__none__":
            include_run_name = True

        page_title = f"Profiling Results / {str(expectation_suite_name)}"
        if data_asset_name:
            page_title += f" / {str(data_asset_name)}"
        if include_run_name:
            page_title += f" / {str(run_name)}"
        page_title += f" / {str(run_time)}"

        return RenderedDocumentContent(
            **{
                "renderer_type":
                "ProfilingResultsPageRenderer",
                "page_title":
                page_title,
                "expectation_suite_name":
                expectation_suite_name,
                "utm_medium":
                "profiling-results-page",
                "batch_kwargs":
                batch_kwargs if "batch_kwargs" in
                validation_results.meta else None,
                "batch_spec":
                batch_kwargs if "batch_spec" in
                validation_results.meta else None,
                "sections": [
                    self._overview_section_renderer.render(
                        validation_results, section_name="Overview")
                ] + [
                    self._column_section_renderer.render(
                        columns[column],
                        section_name=column,
                        column_type=column_types.get(column),
                    ) for column in ordered_columns
                ],
            })
Ejemplo n.º 5
0
    def render(
        self,
        validation_results: ExpectationSuiteValidationResult,
        evaluation_parameters=None,
    ):
        # Gather run identifiers
        run_name, run_time = self._parse_run_values(validation_results)
        expectation_suite_name = validation_results.meta[
            "expectation_suite_name"]
        batch_kwargs = (validation_results.meta.get("batch_kwargs", {})
                        or validation_results.meta.get("batch_spec", {}) or {})

        # Add datasource key to batch_kwargs if missing
        if "datasource" not in batch_kwargs and "datasource" not in batch_kwargs:
            # Check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern
            if len(expectation_suite_name.split(".")) == 4:
                batch_kwargs["datasource"] = expectation_suite_name.split(
                    ".")[0]

        columns = self._group_evrs_by_column(validation_results,
                                             expectation_suite_name)
        overview_content_blocks = [
            self._render_validation_header(validation_results),
            self._render_validation_statistics(
                validation_results=validation_results),
        ]

        collapse_content_blocks = [
            self._render_validation_info(validation_results=validation_results)
        ]
        collapse_content_block = self._generate_collapse_content_block(
            collapse_content_blocks, validation_results)

        if not self.run_info_at_end:
            overview_content_blocks.append(collapse_content_block)

        sections = self._collect_rendered_document_content_sections(
            validation_results,
            overview_content_blocks,
            collapse_content_blocks,
            columns,
        )

        # Determine whether we have a custom run_name
        data_asset_name = batch_kwargs.get("data_asset_name", "")
        page_title = self._determine_page_title(run_name, run_time,
                                                data_asset_name,
                                                expectation_suite_name)

        return RenderedDocumentContent(
            **{
                "renderer_type":
                "ValidationResultsPageRenderer",
                "page_title":
                page_title,
                "batch_kwargs":
                batch_kwargs if "batch_kwargs" in
                validation_results.meta else None,
                "batch_spec":
                batch_kwargs if "batch_spec" in
                validation_results.meta else None,
                "expectation_suite_name":
                expectation_suite_name,
                "sections":
                sections,
                "utm_medium":
                "validation-results-page",
            })
 def deserialize(self, key, value):
     return RenderedDocumentContent(**loads(value))
    def render(cls, index_links_dict):
        sections = []
        cta_object = index_links_dict.pop("cta_object", None)

        try:
            content_blocks = []
            # site name header
            site_name_header_block = RenderedHeaderContent(
                **{
                    "content_block_type":
                    "header",
                    "header":
                    RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "$title_prefix | $site_name",
                                "params": {
                                    "site_name": index_links_dict.get(
                                        "site_name"),
                                    "title_prefix": "Data Docs",
                                },
                                "styling": {
                                    "params": {
                                        "title_prefix": {
                                            "tag": "strong"
                                        }
                                    }
                                },
                            },
                        }),
                    "styling": {
                        "classes": ["col-12", "ge-index-page-site-name-title"],
                        "header": {
                            "classes": ["alert", "alert-secondary"]
                        },
                    },
                })
            content_blocks.append(site_name_header_block)

            tabs = []

            if index_links_dict.get("validations_links"):
                tabs.append({
                    "tab_name":
                    "Validation Results",
                    "tab_content":
                    cls._generate_validation_results_link_table(
                        index_links_dict),
                })
            if index_links_dict.get("profiling_links"):
                tabs.append({
                    "tab_name":
                    "Profiling Results",
                    "tab_content":
                    cls._generate_profiling_results_link_table(
                        index_links_dict),
                })
            if index_links_dict.get("expectations_links"):
                tabs.append({
                    "tab_name":
                    "Expectation Suites",
                    "tab_content":
                    cls._generate_expectation_suites_link_table(
                        index_links_dict),
                })

            tabs_content_block = RenderedTabsContent(
                **{
                    "tabs": tabs,
                    "styling": {
                        "classes": ["col-12", "ge-index-page-tabs-container"],
                    },
                })

            content_blocks.append(tabs_content_block)

            section = RenderedSectionContent(
                **{
                    "section_name": index_links_dict.get("site_name"),
                    "content_blocks": content_blocks,
                })
            sections.append(section)

            index_page_document = RenderedDocumentContent(
                **{
                    "renderer_type": "SiteIndexPageRenderer",
                    "utm_medium": "index-page",
                    "sections": sections,
                })

            if cta_object:
                index_page_document.cta_footer = CallToActionRenderer.render(
                    cta_object)

            return index_page_document

        except Exception as e:
            exception_message = f"""\
An unexpected Exception occurred during data docs rendering.  Because of this error, certain parts of data docs will \
not be rendered properly and/or may not appear altogether.  Please use the trace, included in this message, to \
diagnose and repair the underlying issue.  Detailed information follows:
            """
            exception_traceback = traceback.format_exc()
            exception_message += (
                f'{type(e).__name__}: "{str(e)}".  Traceback: "{exception_traceback}".'
            )
            logger.error(exception_message)
    def render(cls, index_links_dict):

        sections = []

        for source, generators in index_links_dict.items():
            content_blocks = []

            # datasource header
            source_header_block = RenderedComponentContent(
                **{
                    "content_block_type": "header",
                    "header": source,
                    "styling": {
                        "classes": ["col-12"],
                        "header": {
                            "classes": ["alert", "alert-secondary"]
                        }
                    }
                })
            content_blocks.append(source_header_block)

            # generator header
            for generator, data_assets in generators.items():
                generator_header_block = RenderedComponentContent(
                    **{
                        "content_block_type": "header",
                        "header": generator,
                        "styling": {
                            "classes": ["col-12", "ml-4"],
                        }
                    })
                content_blocks.append(generator_header_block)

                horizontal_rule = RenderedComponentContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "",
                            "params": {},
                            "tag": "hr"
                        },
                        "styling": {
                            "classes": ["col-12"],
                        }
                    })
                content_blocks.append(horizontal_rule)

                generator_table_rows = []
                generator_table_header_row = ["Data Asset"]

                header_dict = OrderedDict(
                    [["profiling_links", "Profiling Results"],
                     ["expectation_suite_links", "Expectation Suite"],
                     ["validation_links", "Validation Results"]])

                for link_lists_key, header in header_dict.items():
                    for data_asset, link_lists in data_assets.items():
                        if header in generator_table_header_row:
                            continue
                        if link_lists[link_lists_key]:
                            generator_table_header_row.append(header)

                generator_table = RenderedComponentContent(
                    **{
                        "content_block_type": "table",
                        "header_row": generator_table_header_row,
                        "table": generator_table_rows,
                        "styling": {
                            "classes": ["col-12"],
                            "styles": {
                                "margin-top": "10px"
                            },
                            "body": {
                                "classes": ["table", "table-sm"]
                            }
                        }
                    })
                # data_assets
                for data_asset, link_lists in data_assets.items():
                    generator_table_rows += cls._generate_data_asset_table_section(
                        data_asset, link_lists)

                content_blocks.append(generator_table)

            section = RenderedSectionContent(**{
                "section_name": source,
                "content_blocks": content_blocks
            })
            sections.append(section)

        return RenderedDocumentContent(**{
            "utm_medium": "index-page",
            "sections": sections
        })
Ejemplo n.º 9
0
    def render(cls, index_links_dict):

        sections = []
        cta_object = index_links_dict.pop("cta_object", None)

        try:
            content_blocks = []
            # site name header
            site_name_header_block = RenderedHeaderContent(
                **{
                    "content_block_type":
                    "header",
                    "header":
                    RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "$title_prefix | $site_name",
                                "params": {
                                    "site_name": index_links_dict.get(
                                        "site_name"),
                                    "title_prefix": "Data Docs"
                                },
                                "styling": {
                                    "params": {
                                        "title_prefix": {
                                            "tag": "strong"
                                        }
                                    }
                                },
                            }
                        }),
                    "styling": {
                        "classes": ["col-12", "ge-index-page-site-name-title"],
                        "header": {
                            "classes": ["alert", "alert-secondary"]
                        }
                    }
                })
            content_blocks.append(site_name_header_block)

            table_rows = []
            table_header_row = []
            link_list_keys_to_render = []

            header_dict = OrderedDict(
                [["expectations_links", "Expectation Suite"],
                 ["validations_links", "Validation Results (run_id)"]])

            for link_lists_key, header in header_dict.items():
                if index_links_dict.get(link_lists_key):
                    class_header_str = link_lists_key.replace("_", "-")
                    class_str = "ge-index-page-table-{}-header".format(
                        class_header_str)
                    header = RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": header,
                                "params": {},
                                "styling": {
                                    "classes": [class_str],
                                }
                            }
                        })
                    table_header_row.append(header)
                    link_list_keys_to_render.append(link_lists_key)

            generator_table = RenderedTableContent(
                **{
                    "content_block_type": "table",
                    "header_row": table_header_row,
                    "table": table_rows,
                    "styling": {
                        "classes": ["col-12", "ge-index-page-table-container"],
                        "styles": {
                            "margin-top": "10px"
                        },
                        "body": {
                            "classes": [
                                "table", "table-sm",
                                "ge-index-page-generator-table"
                            ]
                        }
                    }
                })

            table_rows += cls._generate_links_table_rows(
                index_links_dict,
                link_list_keys_to_render=link_list_keys_to_render)

            content_blocks.append(generator_table)

            if index_links_dict.get("profiling_links"):
                profiling_table_rows = []
                for profiling_link_dict in index_links_dict.get(
                        "profiling_links"):
                    profiling_table_rows.append([
                        RenderedStringTemplateContent(
                            **{
                                "content_block_type": "string_template",
                                "string_template": {
                                    "template": "$link_text",
                                    "params": {
                                        "link_text":
                                        profiling_link_dict[
                                            "expectation_suite_name"] + "." +
                                        profiling_link_dict["batch_identifier"]
                                    },
                                    "tag": "a",
                                    "styling": {
                                        "attributes": {
                                            "href":
                                            profiling_link_dict["filepath"]
                                        },
                                        "classes": [
                                            "ge-index-page-table-expectation-suite-link"
                                        ]
                                    }
                                },
                            })
                    ])
                content_blocks.append(
                    RenderedTableContent(
                        **{
                            "content_block_type": "table",
                            "header_row": ["Profiling Results"],
                            "table": profiling_table_rows,
                            "styling": {
                                "classes":
                                ["col-12", "ge-index-page-table-container"],
                                "styles": {
                                    "margin-top": "10px"
                                },
                                "body": {
                                    "classes": [
                                        "table", "table-sm",
                                        "ge-index-page-generator-table"
                                    ]
                                }
                            }
                        }))

            section = RenderedSectionContent(
                **{
                    "section_name": index_links_dict.get("site_name"),
                    "content_blocks": content_blocks
                })
            sections.append(section)

            index_page_document = RenderedDocumentContent(
                **{
                    "renderer_type": "SiteIndexPageRenderer",
                    "utm_medium": "index-page",
                    "sections": sections
                })

            if cta_object:
                index_page_document.cta_footer = CallToActionRenderer.render(
                    cta_object)

            return index_page_document

        except Exception as e:
            exception_message = f'''\
An unexpected Exception occurred during data docs rendering.  Because of this error, certain parts of data docs will \
not be rendered properly and/or may not appear altogether.  Please use the trace, included in this message, to \
diagnose and repair the underlying issue.  Detailed information follows:  
            '''
            exception_traceback = traceback.format_exc()
            exception_message += f'{type(e).__name__}: "{str(e)}".  Traceback: "{exception_traceback}".'
            logger.error(exception_message, e, exc_info=True)
Ejemplo n.º 10
0
    def render(cls, ge_dict=None):
        if ge_dict is None:
            ge_dict = {}

        return RenderedDocumentContent(**{
            "renderer_type": "CustomValidationResultsPageRenderer",
            "data_asset_name": "my_data_asset_name",
            "full_data_asset_identifier": "my_datasource/my_generator/my_generator_asset",
            "page_title": "My Page Title",
            "sections": [
                RenderedSectionContent(**{
                    "section_name": "Header Content Block",
                    "content_blocks": [
                        cls._get_header_content_block(header="Header Content Block", subheader="subheader")]
                }),
                RenderedSectionContent(**{
                    "section_name": "Bullet List Content Block",
                    "content_blocks": [
                        cls._get_header_content_block(header="Bullet List Content Block"),
                        cls._get_bullet_list_content_block(header="My Important List",
                                                           subheader="Unremarkable Subheader")
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "Table Content Block",
                    "content_blocks": [
                        cls._get_header_content_block(header="Table Content Block"),
                        cls._get_table_content_block(header="My Big Data Table"),
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "Value List Content Block",
                    "content_blocks": [
                        cls._get_header_content_block(header="Value List Content Block"),
                        cls._get_value_list_content_block(header="My Name Value List"),
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "Graph Content Block",
                    "content_blocks": [
                        cls._get_header_content_block(header="Graph Content Block"),
                        cls._get_graph_content_block(header="My Big Data Graph"),
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "String Template Content Block With Icon",
                    "content_blocks": [
                        cls._get_header_content_block(header="String Template Content Block With Icon"),
                        cls._get_string_template_content_block()
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "String Template Content Block With Tooltip",
                    "content_blocks": [
                        cls._get_header_content_block(header="String Template Content Block With Tooltip"),
                        cls._get_tooltip_string_template_content_block()
                    ]
                }),
                RenderedSectionContent(**{
                    "section_name": "Multiple Content Block Section",
                    "content_blocks": [
                        cls._get_header_content_block(header="Multiple Content Block Section"),
                        cls._get_graph_content_block(header="My col-4 Graph", col=4),
                        cls._get_graph_content_block(header="My col-4 Graph", col=4),
                        cls._get_graph_content_block(header="My col-4 Graph", col=4),
                        cls._get_table_content_block(header="My col-6 Table", col=6),
                        cls._get_bullet_list_content_block(header="My col-6 List", subheader="subheader", col=6)
                    ]
                }),
            ]
        })
Ejemplo n.º 11
0
    def render(cls, index_links_dict):

        sections = []
        cta_object = index_links_dict.pop("cta_object", None)

        for source, generators in index_links_dict.items():
            content_blocks = []

            # datasource header
            source_header_block = RenderedComponentContent(
                **{
                    "content_block_type": "header",
                    "header": {
                        "template": "$title_prefix | $source",
                        "params": {
                            "source": source,
                            "title_prefix": "Datasource"
                        },
                        "styling": {
                            "params": {
                                "title_prefix": {
                                    "tag": "strong"
                                }
                            }
                        },
                    },
                    "styling": {
                        "classes":
                        ["col-12", "ge-index-page-datasource-title"],
                        "header": {
                            "classes": ["alert", "alert-secondary"]
                        }
                    }
                })
            content_blocks.append(source_header_block)

            # generator header
            for generator, data_assets in generators.items():
                generator_header_block = RenderedComponentContent(
                    **{
                        "content_block_type": "header",
                        "subheader": {
                            "template": "$title_prefix | $generator",
                            "params": {
                                "generator": generator,
                                "title_prefix": "Data Asset Generator"
                            },
                            "styling": {
                                "params": {
                                    "title_prefix": {
                                        "tag": "strong"
                                    }
                                }
                            },
                        },
                        "styling": {
                            "classes": [
                                "col-12", "ml-4",
                                "ge-index-page-generator-title"
                            ],
                        }
                    })
                content_blocks.append(generator_header_block)

                generator_table_rows = []
                generator_table_header_row = [
                    RenderedComponentContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "Data Asset",
                                "params": {},
                                "styling": {
                                    "classes": [
                                        "ge-index-page-generator-table-data-asset-header"
                                    ],
                                }
                            }
                        })
                ]
                link_list_keys_to_render = []

                header_dict = OrderedDict(
                    [["profiling_links", "Profiling Results"],
                     ["expectations_links", "Expectation Suite"],
                     ["validations_links", "Validation Results"]])

                for link_lists_key, header in header_dict.items():
                    for data_asset, link_lists in data_assets.items():
                        if header in generator_table_header_row:
                            continue
                        if link_lists.get(link_lists_key):
                            class_header_str = link_lists_key.replace("_", "-")
                            class_str = "ge-index-page-generator-table-{}-header".format(
                                class_header_str)
                            header = RenderedComponentContent(
                                **{
                                    "content_block_type": "string_template",
                                    "string_template": {
                                        "template": header,
                                        "params": {},
                                        "styling": {
                                            "classes": [class_str],
                                        }
                                    }
                                })
                            generator_table_header_row.append(header)
                            link_list_keys_to_render.append(link_lists_key)

                generator_table = RenderedComponentContent(
                    **{
                        "content_block_type": "table",
                        "header_row": generator_table_header_row,
                        "table": generator_table_rows,
                        "styling": {
                            "classes": [
                                "col-12",
                                "ge-index-page-generator-table-container",
                                "pl-5", "pr-4"
                            ],
                            "styles": {
                                "margin-top": "10px"
                            },
                            "body": {
                                "classes": [
                                    "table", "table-sm",
                                    "ge-index-page-generator-table"
                                ]
                            }
                        }
                    })
                # data_assets
                for data_asset, link_lists in data_assets.items():
                    generator_table_rows += cls._generate_data_asset_table_section(
                        data_asset,
                        link_lists,
                        link_list_keys_to_render=link_list_keys_to_render)

                content_blocks.append(generator_table)

            section = RenderedSectionContent(**{
                "section_name": source,
                "content_blocks": content_blocks
            })
            sections.append(section)

        index_page_document = RenderedDocumentContent(**{
            "utm_medium": "index-page",
            "sections": sections
        })

        if cta_object:
            index_page_document["cta_footer"] = CallToActionRenderer.render(
                cta_object)

        return index_page_document
    def render(cls, index_links_dict):

        sections = []
        cta_object = index_links_dict.pop("cta_object", None)

        try:
            content_blocks = []
            # site name header
            site_name_header_block = RenderedHeaderContent(
                **{
                    "content_block_type":
                    "header",
                    "header":
                    RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "$title_prefix | $site_name",
                                "params": {
                                    "site_name": index_links_dict.get(
                                        "site_name"),
                                    "title_prefix": "Data Docs"
                                },
                                "styling": {
                                    "params": {
                                        "title_prefix": {
                                            "tag": "strong"
                                        }
                                    }
                                },
                            }
                        }),
                    "styling": {
                        "classes": ["col-12", "ge-index-page-site-name-title"],
                        "header": {
                            "classes": ["alert", "alert-secondary"]
                        }
                    }
                })
            content_blocks.append(site_name_header_block)

            table_rows = []
            table_header_row = []
            link_list_keys_to_render = []

            header_dict = OrderedDict(
                [["expectations_links", "Expectation Suite"],
                 ["validations_links", "Validation Results (run_id)"]])

            for link_lists_key, header in header_dict.items():
                if index_links_dict.get(link_lists_key):
                    class_header_str = link_lists_key.replace("_", "-")
                    class_str = "ge-index-page-table-{}-header".format(
                        class_header_str)
                    header = RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": header,
                                "params": {},
                                "styling": {
                                    "classes": [class_str],
                                }
                            }
                        })
                    table_header_row.append(header)
                    link_list_keys_to_render.append(link_lists_key)

            generator_table = RenderedTableContent(
                **{
                    "content_block_type": "table",
                    "header_row": table_header_row,
                    "table": table_rows,
                    "styling": {
                        "classes": ["col-12", "ge-index-page-table-container"],
                        "styles": {
                            "margin-top": "10px"
                        },
                        "body": {
                            "classes": [
                                "table", "table-sm",
                                "ge-index-page-generator-table"
                            ]
                        }
                    }
                })

            table_rows += cls._generate_links_table_rows(
                index_links_dict,
                link_list_keys_to_render=link_list_keys_to_render)

            content_blocks.append(generator_table)

            if index_links_dict.get("profiling_links"):
                profiling_table_rows = []
                for profiling_link_dict in index_links_dict.get(
                        "profiling_links"):
                    profiling_table_rows.append([
                        RenderedStringTemplateContent(
                            **{
                                "content_block_type": "string_template",
                                "string_template": {
                                    "template": "$link_text",
                                    "params": {
                                        "link_text":
                                        profiling_link_dict[
                                            "expectation_suite_name"] + "." +
                                        profiling_link_dict["batch_identifier"]
                                    },
                                    "tag": "a",
                                    "styling": {
                                        "attributes": {
                                            "href":
                                            profiling_link_dict["filepath"]
                                        },
                                        "classes": [
                                            "ge-index-page-table-expectation-suite-link"
                                        ]
                                    }
                                },
                            })
                    ])
                content_blocks.append(
                    RenderedTableContent(
                        **{
                            "content_block_type": "table",
                            "header_row": ["Profiling Results"],
                            "table": profiling_table_rows,
                            "styling": {
                                "classes":
                                ["col-12", "ge-index-page-table-container"],
                                "styles": {
                                    "margin-top": "10px"
                                },
                                "body": {
                                    "classes": [
                                        "table", "table-sm",
                                        "ge-index-page-generator-table"
                                    ]
                                }
                            }
                        }))

            section = RenderedSectionContent(
                **{
                    "section_name": index_links_dict.get("site_name"),
                    "content_blocks": content_blocks
                })
            sections.append(section)

            index_page_document = RenderedDocumentContent(
                **{
                    "renderer_type": "SiteIndexPageRenderer",
                    "utm_medium": "index-page",
                    "sections": sections
                })

            if cta_object:
                index_page_document.cta_footer = CallToActionRenderer.render(
                    cta_object)

            return index_page_document

        except Exception as e:
            logger.error("Exception occurred during data docs rendering: ",
                         e,
                         exc_info=True)
Ejemplo n.º 13
0
def test_render_DefaultJinjaPageView_meta_info():
    validation_results = {
        "results": [],
        "statistics": {
            "evaluated_expectations": 156,
            "successful_expectations": 139,
            "unsuccessful_expectations": 17,
            "success_percent": 89.1025641025641
        },
        "meta": {
            "great_expectations.__version__": "0.7.0-beta",
            "data_asset_name": "tetanusvaricella",
            "expectation_suite_name": "my_suite",
            "run_id": "2019-06-25T14:58:09.960521",
            "batch_kwargs": {
                "path":
                "/Users/user/project_data/public_healthcare_datasets/tetanusvaricella/tetvardata.csv",
                "timestamp": 1561474688.693565
            }
        }
    }

    document = RenderedDocumentContent(
        dict_to_ordered_dict(
            ProfilingResultsPageRenderer().render(validation_results)))
    html = DefaultJinjaPageView().render(document)
    print(html)

    expected_html = """
<!DOCTYPE html>
<html>
  <head>
    <title>Data documentation compiled by Great Expectations</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>

    
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>

    <style>  body {
    position: relative;
  }
  .container {
    padding-top: 50px;
  }
  .sticky {
    position: -webkit-sticky;
    position: sticky;
    max-height: 90vh;
    overflow-y: auto;
    top: 15px;
  }

  .ge-section {
    clear:both;
    margin-bottom: 30px;
    padding-bottom: 20px;
  }

  .triangle {
    border: solid #222;
    border-width: 0 1px 1px 0;
    display: inline;
    cursor: pointer;
    padding: 3px;
    position: absolute;
    right: 0;
    margin-top: 10px;

    transform: rotate(40deg);
    -webkit-transform: rotate(40deg);
    transition: .3s transform ease-in-out;
  }

  .collapsed .triangle{
    transform: rotate(-140deg);
    -webkit-transform: rotate(-140deg);
    transition: .3s transform ease-in-out;
  }

  .popover {
    max-width: 100%;
  }

  .cooltip {
    display:inline-block;
    position:relative;
    text-align:left;
    cursor:pointer;
  }

  .cooltip .top {
    min-width:200px;
    top:-6px;
    left:50%;
    transform:translate(-50%, -100%);
    padding:10px 20px;
    color:#FFFFFF;
    background-color:#222222;
    font-weight:normal;
    font-size:13px;
    border-radius:8px;
    position:absolute;
    z-index:99999999 !important;
    box-sizing:border-box;
    box-shadow:0 1px 8px rgba(0,0,0,0.5);
    display:none;
    }

  .cooltip:hover .top {
      display:block;
      z-index:99999999 !important;
  }

  .cooltip .top i {
      position:absolute;
      top:100%;
      left:50%;
      margin-left:-12px;
      width:24px;
      height:12px;
      overflow:hidden;
  }

  .cooltip .top i::after {
      content:'';
      position:absolute;
      width:12px;
      height:12px;
      left:50%;
      transform:translate(-50%,-50%) rotate(45deg);
      background-color:#222222;
      box-shadow:0 1px 8px rgba(0,0,0,0.5);
  }

  ul {
    padding-inline-start: 20px;
  }

  .table-cell-frame {
      overflow-y: auto;
      max-height: 200px;
  }

  .table-cell-frame ul {
    padding-bottom: 20px
  }

  .table-cell-frame::-webkit-scrollbar {
      -webkit-appearance: none;
  }

  .table-cell-frame::-webkit-scrollbar:vertical {
      width: 11px;
  }

  .table-cell-frame::-webkit-scrollbar:horizontal {
      height: 11px;
  }

  .table-cell-frame::-webkit-scrollbar-thumb {
      border-radius: 8px;
      border: 2px solid white; /* should match background, can't be transparent */
      background-color: rgba(0, 0, 0, .5);
  }</style>
    <style></style>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega-lite.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega-embed.js"></script>
    <script src="https://kit.fontawesome.com/8217dffd95.js"></script>
  </head>

  <body
        data-spy="scroll"
        data-target="#navigation"
        data-offset="50"
    >
    
<nav aria-label="breadcrumb">
    <ol class="ge-breadcrumbs breadcrumb">
        
          <li class="ge-breadcrumbs-item breadcrumb-item"><a href="../../../../../index.html">Home</a></li>
        
        
            <li class="ge-breadcrumbs-item breadcrumb-item">tetanusvaricella</li>
        
        <li class="ge-breadcrumbs-item breadcrumb-item active" aria-current="page">2019-06-25T14:58:09.960521-my_suite-ProfilingResults</li>
    </ol>
</nav>


    <div class="container-fluid px-3">
      <div class="row">
        <div class="col-2 navbar-collapse">
          <nav id="navigation" class="navbar navbar-light bg-light sticky d-none d-sm-block ge-navigation-sidebar-container">
    <nav class="nav nav-pills flex-column ge-navigation-sidebar-content">
        <a class="navbar-brand ge-navigation-sidebar-title" href="#" style="white-space: normal; word-break: break-all;overflow-wrap: normal; font-size: 1rem; font-weight: 500;">tetanusvaricella</a>
        
            <a class="nav-link ge-navigation-sidebar-link" href="#section-1">Overview</a>
        
    </nav>
</nav>
        </div>
        <div class="col-md-8 col-lg-8 col-xs-12">
        
          <div id="section-1" class="ge-section container-fluid">
    <div class="row">
    

<div id="section-1-content-block-1" class="col-12" >

    <div id="section-1-content-block-1-header" class="alert alert-secondary" >
    <h3>
        Overview
    </h3></div>

</div>


<div id="section-1-content-block-2" class="col-6" style="margin-top:20px;" >

    <div id="section-1-content-block-2-header" >
        
        <h4>
            Dataset info
        </h4>
        </div>


<table id="section-1-content-block-2-body" class="table table-sm" >
    

    <tr>
        <td id="section-1-content-block-2-cell-1-1" ><div class="table-cell-frame"><span>Number of variables</span></div></td><td id="section-1-content-block-2-cell-1-2" ><div class="table-cell-frame">0</div></td></tr><tr>
        <td id="section-1-content-block-2-cell-2-1" ><div class="table-cell-frame">
                <span class="cooltip" >
                    Number of observations
                    <span class=top>
                        expect_table_row_count_to_be_between
                    </span>
                </span>
            </div></td><td id="section-1-content-block-2-cell-2-2" ><div class="table-cell-frame"><span>--</span></div></td></tr><tr>
        <td id="section-1-content-block-2-cell-3-1" ><div class="table-cell-frame"><span>Missing cells</span></div></td><td id="section-1-content-block-2-cell-3-2" ><div class="table-cell-frame"><span>?</span></div></td></tr></table>

</div>


<div id="section-1-content-block-3" class="col-6 table-responsive" style="margin-top:20px;" >

    <div id="section-1-content-block-3-header" >
        
        <h4>
            Variable types
        </h4>
        </div>


<table id="section-1-content-block-3-body" class="table table-sm" >
    

    <tr>
        <td id="section-1-content-block-3-cell-1-1" ><div class="table-cell-frame"><span>int</span></div></td><td id="section-1-content-block-3-cell-1-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr>
        <td id="section-1-content-block-3-cell-2-1" ><div class="table-cell-frame"><span>float</span></div></td><td id="section-1-content-block-3-cell-2-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr>
        <td id="section-1-content-block-3-cell-3-1" ><div class="table-cell-frame"><span>string</span></div></td><td id="section-1-content-block-3-cell-3-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr>
        <td id="section-1-content-block-3-cell-4-1" ><div class="table-cell-frame"><span>unknown</span></div></td><td id="section-1-content-block-3-cell-4-2" ><div class="table-cell-frame"><span>0</span></div></td></tr></table>

</div>"""

    expected_html_2 = """
</div>
</div>

        </div>
        <div class="col-lg-2 col-md-2 col-xs-12 d-none d-md-block">
            <div>
  <div class="col-12">
    <div class="row">
      <img
        src="https://great-expectations.readthedocs.io/en/latest/_images/generic_dickens_protagonist.png"
        style="
          width: 200px;
          margin-left: auto;
          margin-right: auto;
        ">
    </div>
  </div>
  <div class="col-12">
    <p>
      Documentation autogenerated using
      <a href="https://greatexpectations.io">Great Expectations</a>.
    </p>
  </div>
  <div class="alert alert-danger col-12" role="alert">
      This is a beta feature! Expect changes in API, behavior, and design.
  </div>
</div>
        </div>
        <div class="d-block d-sm-none col-12">
            <div>
              <div class="row">
                <img
                  src="https://great-expectations.readthedocs.io/en/latest/_images/generic_dickens_protagonist.png"
                  style="
                    width: 200px;
                    margin-left: auto;
                    margin-right: auto;
                  ">
              </div>
            </div>
            <div class="col-12">
              <p>
                Documentation autogenerated using
                <a href="https://greatexpectations.io">Great Expectations</a>.
              </p>
            </div>
            <div class="alert alert-danger col-12" role="alert">
                This is a beta feature! Expect changes in API, behavior, and design.
            </div>
          </div>

      </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <script>
        $(window).on('activate.bs.scrollspy', function () {
          document.querySelector(".nav-link.active").scrollIntoViewIfNeeded();
        });
    </script>
  </body>
</html>
"""

    assert expected_html.replace(" ", "").replace("\t", "").replace(
        "\n", "") in html.replace(" ", "").replace("\t", "").replace("\n", "")
    assert expected_html_2.replace(" ", "").replace("\t", "").replace(
        "\n", "") in html.replace(" ", "").replace("\t", "").replace("\n", "")