def expect_column_values_to_not_be_null(cls, ge_object):
     return [[
         RenderedStringTemplateContent(
             **{
                 "content_block_type": "string_template",
                 "string_template": {
                     "template": "Missing (n)",
                     "tooltip": {
                         "content": "expect_column_values_to_not_be_null"
                     }
                 }
             }),
         ge_object.result["unexpected_count"]
         if "unexpected_count" in ge_object.result
         and ge_object.result["unexpected_count"] is not None else "--",
     ],
             [
                 RenderedStringTemplateContent(
                     **{
                         "content_block_type": "string_template",
                         "string_template": {
                             "template": "Missing (%)",
                             "tooltip": {
                                 "content":
                                 "expect_column_values_to_not_be_null"
                             }
                         }
                     }),
                 "%.1f%%" % ge_object.result["unexpected_percent"]
                 if "unexpected_percent" in ge_object.result
                 and ge_object.result["unexpected_percent"] is not None else
                 "--",
             ]]
    def _render_dataset_info(cls, evrs, content_blocks) -> None:
        expect_table_row_count_to_be_between_evr = cls._find_evr_by_type(
            evrs["results"], "expect_table_row_count_to_be_between")

        table_rows = []
        table_rows.append([
            "Number of variables",
            len(cls._get_column_list_from_evrs(evrs)),
        ])

        table_rows.append([
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": "Number of observations",
                        "tooltip": {
                            "content": "expect_table_row_count_to_be_between"
                        },
                        "params": {
                            "tooltip_text": "Number of observations"
                        },
                    },
                }),
            "--" if not expect_table_row_count_to_be_between_evr else
            expect_table_row_count_to_be_between_evr.result["observed_value"],
        ])

        table_rows += [
            [
                "Missing cells",
                cls._get_percentage_missing_cells_str(evrs),
            ],
            # ["Duplicate rows", "0 (0.0%)", ], #TODO: bring back when we have an expectation for this
        ]

        content_blocks.append(
            RenderedTableContent(
                **{
                    "content_block_type":
                    "table",
                    "header":
                    RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "Dataset info",
                                "tag": "h6",
                            },
                        }),
                    "table":
                    table_rows,
                    "styling": {
                        "classes": ["col-6", "mt-1", "p-1"],
                        "body": {
                            "classes": ["table", "table-sm"]
                        },
                    },
                }))
def test_ValidationResultsTableContentBlockRenderer_get_content_block_fn(
        evr_success):
    content_block_fn = ValidationResultsTableContentBlockRenderer._get_content_block_fn(
        "expect_table_row_count_to_be_between")
    content_block_fn_output = content_block_fn(evr_success)

    content_block_fn_expected_output = [[
        RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "$icon",
                    "params": {
                        "icon": "",
                        "markdown_status_icon": "✅"
                    },
                    "styling": {
                        "params": {
                            "icon": {
                                "classes": [
                                    "fas",
                                    "fa-check-circle",
                                    "text-success",
                                ],
                                "tag":
                                "i",
                            }
                        }
                    },
                },
                "styling": {
                    "parent": {
                        "classes": ["hide-succeeded-validation-target-child"]
                    }
                },
            }),
        RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template":
                    "Must have greater than or equal to $min_value rows.",
                    "params": {
                        "min_value": 0,
                        "max_value": None,
                        "result_format": "SUMMARY",
                        "row_condition": None,
                        "condition_parser": None,
                        "strict_max": None,
                        "strict_min": None,
                    },
                    "styling": None,
                },
            }),
        "1,313",
    ]]
    assert content_block_fn_output == content_block_fn_expected_output
Exemple #4
0
    def _render_header(cls, evrs, column_type=None):
        # NOTE: This logic is brittle
        try:
            column_name = evrs[0].expectation_config.kwargs["column"]
        except KeyError:
            column_name = "Table-level expectations"

        return RenderedHeaderContent(
            **{
                "content_block_type":
                "header",
                "header":
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": convert_to_string_and_escape(
                                column_name),
                            "tooltip": {
                                "content": "expect_column_to_exist",
                                "placement": "top"
                            },
                            "tag": "h5",
                            "styling": {
                                "classes": ["m-0", "p-0"]
                            }
                        }
                    }),
                "subheader":
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template":
                            "Type: {column_type}".format(
                                column_type=column_type),
                            "tooltip": {
                                "content":
                                "expect_column_values_to_be_of_type <br>expect_column_values_to_be_in_type_list",
                            },
                            "tag":
                            "h6",
                            "styling": {
                                "classes": ["mt-1", "mb-0"]
                            }
                        }
                    }),
                # {
                #     "template": column_type,
                # },
                "styling": {
                    "classes": ["col-12", "p-0"],
                    "header": {
                        "classes": ["alert", "alert-secondary"]
                    }
                }
            })
Exemple #5
0
    def _missing_content_block_fn(cls,
                                  evr,
                                  styling=None,
                                  include_column_name=True):
        # Only render EVR objects for which an exception was raised
        if evr.exception_info["raised_exception"] is True:
            template_str = "$expectation_type raised an exception: $exception_message"
            if include_column_name:
                template_str = "$column: " + template_str

            try:
                column = evr.expectation_config.kwargs["column"]
            except KeyError:
                column = None
            return [
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": template_str,
                            "params": {
                                "column":
                                column,
                                "expectation_type":
                                evr.expectation_config.expectation_type,
                                "exception_message":
                                evr.exception_info["exception_message"],
                            },
                            "styling": styling,
                        },
                    })
            ]
Exemple #6
0
    def _descriptive_histogram_renderer(
        cls,
        configuration=None,
        result=None,
        language=None,
        runtime_configuration=None,
        **kwargs
    ):
        assert result, "Must pass in result."
        observed_partition_object = result.result["details"]["observed_partition"]
        weights = observed_partition_object["weights"]
        if len(weights) > 60:
            return None

        header = RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "Histogram",
                    "tooltip": {
                        "content": "expect_column_kl_divergence_to_be_less_than"
                    },
                    "tag": "h6",
                },
            }
        )

        return cls._get_kl_divergence_chart(observed_partition_object, header)
Exemple #7
0
    def _render_properties_table(self, evrs):
        evr_list = [
            self._find_evr_by_type(
                evrs, "expect_column_unique_value_count_to_be_between"
            ),
            self._find_evr_by_type(
                evrs, "expect_column_proportion_of_unique_values_to_be_between"
            ),
            self._find_evr_by_type(evrs, "expect_column_values_to_not_be_null"),
            self._find_evr_by_type(evrs, "expect_column_values_to_not_match_regex"),
        ]
        evrs = [evr for evr in evr_list if (evr is not None)]

        if len(evrs) > 0:
            new_content_block = self._properties_table_renderer.render(evrs)
            new_content_block.header = RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {"template": "Properties", "tag": "h6"},
                }
            )
            new_content_block.styling = {
                "classes": ["col-3", "mt-1", "pl-1", "pr-1"],
                "body": {
                    "classes": ["table", "table-sm", "table-unbordered"],
                    "styles": {"width": "100%"},
                },
            }
            return new_content_block
 def _render_validation_success_cell(cls, validation_success):
     return RenderedStringTemplateContent(
         **{
             "content_block_type": "string_template",
             "string_template": {
                 "template": "$validation_success",
                 "params": {
                     "validation_success": ""
                 },
                 "styling": {
                     "params": {
                         "validation_success": {
                             "tag":
                             "i",
                             "classes": [
                                 "fas",
                                 "fa-check-circle",
                                 "text-success",
                                 "ge-success-icon",
                             ] if validation_success else [
                                 "fas",
                                 "fa-times",
                                 "text-danger",
                                 "ge-failed-icon",
                             ],
                         }
                     },
                     "classes":
                     ["ge-index-page-table-validation-links-item"],
                 },
             },
         })
Exemple #9
0
    def _get_kl_divergence_observed_value(cls, evr):
        if not evr.result.get("details"):
            return "--"

        observed_partition_object = evr.result["details"]["observed_partition"]
        observed_distribution = super()._get_kl_divergence_chart(
            observed_partition_object)

        observed_value = (num_to_str(evr.result.get("observed_value"))
                          if evr.result.get("observed_value") else
                          evr.result.get("observed_value"))

        observed_value_content_block = RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "KL Divergence: $observed_value",
                    "params": {
                        "observed_value":
                        str(observed_value) if observed_value else
                        "None (-infinity, infinity, or NaN)",
                    },
                    "styling": {
                        "classes": ["mb-2"]
                    },
                },
            })

        return RenderedContentBlockContainer(
            **{
                "content_block_type":
                "content_block_container",
                "content_blocks":
                [observed_value_content_block, observed_distribution],
            })
Exemple #10
0
    def _prescriptive_renderer(cls,
                               configuration=None,
                               result=None,
                               language=None,
                               runtime_configuration=None,
                               **kwargs):
        runtime_configuration = runtime_configuration or {}
        include_column_name = runtime_configuration.get(
            "include_column_name", True)
        include_column_name = (include_column_name
                               if include_column_name is not None else True)
        styling = runtime_configuration.get("styling")
        params = substitute_none_for_missing(configuration.kwargs,
                                             ["other_table_name"])
        template_str = "Row count must equal the row count of table $other_table_name."

        return [
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": params,
                        "styling": styling,
                    },
                })
        ]
    def _prescriptive_renderer(
        cls,
        configuration=None,
        result=None,
        language=None,
        runtime_configuration=None,
        **kwargs,
    ):
        runtime_configuration = runtime_configuration or {}
        styling = runtime_configuration.get("styling")

        params = substitute_none_for_missing(
            configuration.kwargs,
            [
                "column_list",
                "ignore_row_if",
                "row_condition",
                "condition_parser",
                "mostly",
            ],
        )

        if params["mostly"] is not None and params["mostly"] < 1.0:
            params_with_json_schema["mostly_pct"]["value"] = num_to_str(
                params["mostly"] * 100, precision=15, no_scientific=True)
            template_str = f"Values for given compound columns must be unique together, at least $mostly_pct % of the time: "
        else:
            template_str = (
                f"Values for given compound columns must be unique together: ")

        for idx in range(len(params["column_list"]) - 1):
            template_str += f"$column_list_{str(idx)}, "
            params[f"column_list_{str(idx)}"] = params["column_list"][idx]

        last_idx = len(params["column_list"]) - 1
        template_str += f"$column_list_{str(last_idx)}"
        params[f"column_list_{str(last_idx)}"] = params["column_list"][
            last_idx]

        if params["row_condition"] is not None:
            (
                conditional_template_str,
                conditional_params,
            ) = parse_row_condition_string_pandas_engine(
                params["row_condition"])
            template_str = (conditional_template_str + ", then " +
                            template_str[0].lower() + template_str[1:])
            params.update(conditional_params)

        return [
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": params,
                        "styling": styling,
                    },
                })
        ]
 def _prescriptive_renderer(
     cls,
     configuration=None,
     result=None,
     language=None,
     runtime_configuration=None,
     **kwargs,
 ):
     runtime_configuration = runtime_configuration or {}
     include_column_name = runtime_configuration.get(
         "include_column_name", True)
     include_column_name = (include_column_name
                            if include_column_name is not None else True)
     styling = runtime_configuration.get("styling")
     params = substitute_none_for_missing(
         configuration.kwargs,
         ["column", "mostly", "row_condition", "condition_parser"],
     )
     return [
         RenderedStringTemplateContent(
             **{
                 "content_block_type": "string_template",
                 "string_template": {
                     "template": template_str,
                     "params": params,
                     "styling": styling,
                 },
             })
     ]
Exemple #13
0
 def _get_header_content_block(cls,
                               header="",
                               subheader="",
                               highlight=True):
     return RenderedHeaderContent(
         **{
             "content_block_type":
             "header",
             "header":
             RenderedStringTemplateContent(
                 **{
                     "content_block_type": "string_template",
                     "string_template": {
                         "template": header,
                     },
                 }),
             "subheader":
             subheader,
             "styling": {
                 "classes": ["col-12"],
                 "header": {
                     "classes":
                     ["alert", "alert-secondary"] if highlight else []
                 },
             },
         })
Exemple #14
0
 def _missing_content_block_fn(
     cls,
     configuration=None,
     result=None,
     language=None,
     runtime_configuration=None,
     **kwargs,
 ):
     return [
         RenderedStringTemplateContent(
             **{
                 "content_block_type": "string_template",
                 "styling": {
                     "parent": {
                         "classes": ["alert", "alert-warning"]
                     }
                 },
                 "string_template": {
                     "template": "$expectation_type(**$kwargs)",
                     "params": {
                         "expectation_type": configuration.expectation_type,
                         "kwargs": configuration.kwargs,
                     },
                     "styling": {
                         "params": {
                             "expectation_type": {
                                 "classes": ["badge", "badge-warning"],
                             }
                         }
                     },
                 },
             })
     ]
    def _prescriptive_renderer(
        cls,
        configuration: ExpectationConfiguration = None,
        result: ExpectationValidationResult = None,
        language: str = None,
        runtime_configuration: dict = None,
        **kwargs,
    ) -> List[
        Union[
            dict,
            str,
            RenderedStringTemplateContent,
            RenderedTableContent,
            RenderedBulletListContent,
            RenderedGraphContent,
            Any,
        ]
    ]:
        runtime_configuration = runtime_configuration or {}
        include_column_name = runtime_configuration.get("include_column_name", True)
        include_column_name = (
            include_column_name if include_column_name is not None else True
        )
        styling = runtime_configuration.get("styling")
        params = substitute_none_for_missing(
            configuration.kwargs,
            [
                "column",
                "word",
                "provider",
                "mostly",
            ],
        )

        if params["mostly"] is None:
            template_str = "values must be lat lon and contain $word when reverse geocoded by $provider"
        else:
            if params["mostly"] is not None:
                params["mostly_pct"] = num_to_str(
                    params["mostly"] * 100, precision=15, no_scientific=True
                )
                template_str += ", at least $mostly_pct % of the time."
            else:
                template_str += "."

        if include_column_name:
            template_str = f"$column {template_str}"

        return [
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": params,
                        "styling": styling,
                    },
                }
            )
        ]
 def _render_header(cls, evrs, content_blocks) -> None:
     content_blocks.append(
         RenderedHeaderContent(
             **{
                 "content_block_type":
                 "header",
                 "header":
                 RenderedStringTemplateContent(
                     **{
                         "content_block_type": "string_template",
                         "string_template": {
                             "template": "Overview",
                             "tag": "h5",
                             "styling": {
                                 "classes": ["m-0"]
                             },
                         },
                     }),
                 "styling": {
                     "classes": ["col-12", "p-0"],
                     "header": {
                         "classes": ["alert", "alert-secondary"]
                     },
                 },
             }))
 def _get_string_template_content_block(cls):
     return RenderedStringTemplateContent(
         **{
             "content_block_type": "string_template",
             "string_template": {
                 "template": "$icon This is a Font Awesome Icon, using a param-level custom tag\n$red_text\n$bold_serif",
                 "params": {
                     "icon": "",
                     "red_text": "And this is red text!",
                     "bold_serif": "And this is big, bold serif text using style attribute...",
                 },
                 "styling": {
                     "params": {
                         "icon": {
                             "classes": ["fas", "fa-check-circle", "text-success"],
                             "tag": "i",
                         },
                         "red_text": {"classes": ["text-danger"]},
                         "bold_serif": {
                             "styles": {
                                 "font-size": "22px",
                                 "font-weight": "bold",
                                 "font-family": "serif",
                             }
                         },
                     }
                 },
             },
             "styling": {"classes": ["col-12"], "styles": {"margin-top": "20px"},},
         }
     )
    def _render_expectation_types(cls, evrs, content_blocks):
        # NOTE: The evr-fetching function is an kinda similar to the code other_section_
        # renderer.ProfilingResultsOverviewSectionRenderer._render_expectation_types

        # type_counts = defaultdict(int)

        # for evr in evrs:
        #     type_counts[evr.expectation_config.expectation_type] += 1

        # bullet_list = sorted(type_counts.items(), key=lambda kv: -1*kv[1])

        bullet_list = [{
            "content_block_type": "string_template",
            "string_template": {
                "template": "$expectation_type $is_passing",
                "params": {
                    "expectation_type": evr.expectation_config.expectation_type,
                    "is_passing": str(evr.success),
                },
                "styling": {
                    "classes": ["list-group-item", "d-flex", "justify-content-between", "align-items-center"],
                    "params": {
                        "is_passing": {
                            "classes": ["badge", "badge-secondary", "badge-pill"],
                        }
                    },
                }
            }
        } for evr in evrs]

        content_blocks.append(RenderedBulletListContent(**{
            "content_block_type": "bullet_list",
            "header": RenderedStringTemplateContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": 'Expectation types <span class="mr-3 triangle"></span>',
                    "tag": "h6"
                }
            }),
            "bullet_list": bullet_list,
            "styling": {
                "classes": ["col-12", "mt-1"],
                "header": {
                    "classes": ["collapsed"],
                    "attributes": {
                        "data-toggle": "collapse",
                        "href": "#{{content_block_id}}-body",
                        "role": "button",
                        "aria-expanded": "true",
                        "aria-controls": "collapseExample",
                    },
                    "styles": {
                        "cursor": "pointer",
                    }
                },
                "body": {
                    "classes": ["list-group", "collapse"],
                },
            },
        }))
Exemple #19
0
    def _diagnostic_observed_value_renderer(cls,
                                            configuration=None,
                                            result=None,
                                            language=None,
                                            runtime_configuration=None,
                                            **kwargs):
        if not result.result.get("observed_value"):
            return "--"

        self_table_row_count = num_to_str(
            result.result["observed_value"]["self"])
        other_table_row_count = num_to_str(
            result.result["observed_value"]["other"])

        return RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template":
                    "Row Count: $self_table_row_count<br>Other Table Row Count: $other_table_row_count",
                    "params": {
                        "self_table_row_count": self_table_row_count,
                        "other_table_row_count": other_table_row_count,
                    },
                    "styling": {
                        "classes": ["mb-2"]
                    },
                },
            })
    def _render_variable_types(cls, evrs, content_blocks) -> None:

        column_types = cls._get_column_types(evrs)
        # TODO: check if we have the information to make this statement. Do all columns have type expectations?
        column_type_counter = Counter(column_types.values())
        table_rows = [
            [type, str(column_type_counter[type])] for type in
            ["int", "float", "string", "datetime", "bool", "unknown"]
        ]

        content_blocks.append(
            RenderedTableContent(
                **{
                    "content_block_type":
                    "table",
                    "header":
                    RenderedStringTemplateContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "Variable types",
                                "tag": "h6",
                            },
                        }),
                    "table":
                    table_rows,
                    "styling": {
                        "classes":
                        ["col-6", "table-responsive", "mt-1", "p-1"],
                        "body": {
                            "classes": ["table", "table-sm"]
                        },
                    },
                }))
Exemple #21
0
    def _prescriptive_renderer(
        cls,
        configuration=None,
        result=None,
        language=None,
        runtime_configuration=None,
        **kwargs,
    ):
        runtime_configuration = runtime_configuration or {}
        include_column_name = runtime_configuration.get(
            "include_column_name", True)
        include_column_name = (include_column_name
                               if include_column_name is not None else True)
        styling = runtime_configuration.get("styling")
        params = substitute_none_for_missing(
            configuration.kwargs,
            [
                "column", "value_set", "ties_okay", "row_condition",
                "condition_parser"
            ],
        )

        if params["value_set"] is None or len(params["value_set"]) == 0:
            values_string = "[ ]"
        else:
            for i, v in enumerate(params["value_set"]):
                params["v__" + str(i)] = v

            values_string = " ".join(
                ["$v__" + str(i) for i, v in enumerate(params["value_set"])])

        template_str = ("most common value must belong to this set: " +
                        values_string + ".")

        if params.get("ties_okay"):
            template_str += " Values outside this set that are as common (but not more common) are allowed."

        if include_column_name:
            template_str = "$column " + template_str

        if params["row_condition"] is not None:
            (
                conditional_template_str,
                conditional_params,
            ) = parse_row_condition_string_pandas_engine(
                params["row_condition"])
            template_str = conditional_template_str + ", then " + template_str
            params.update(conditional_params)

        return [
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": params,
                        "styling": styling,
                    },
                })
        ]
Exemple #22
0
    def _prescriptive_renderer(
        cls,
        configuration=None,
        result=None,
        language=None,
        runtime_configuration=None,
        **kwargs,
    ):
        runtime_configuration = runtime_configuration or {}
        include_column_name = runtime_configuration.get(
            "include_column_name", True)
        include_column_name = (include_column_name
                               if include_column_name is not None else True)
        styling = runtime_configuration.get("styling")
        params = substitute_none_for_missing(configuration.kwargs,
                                             ["column_A", "column_B"])
        if (params["column_A"] is None) or (params["column_B"] is None):
            template_str = " unrecognized kwargs for expect_column_pair_cramers_phi_value_to_be_less_than: missing column."
        else:
            template_str = "Values in $column_A and $column_B must be independent."
        rendered_string_template_content = RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": template_str,
                    "params": params,
                    "styling": styling,
                },
            })

        return [rendered_string_template_content]
Exemple #23
0
    def _render_histogram(self, evrs):
        # NOTE: This code is very brittle
        kl_divergence_evr = self._find_evr_by_type(
            evrs, "expect_column_kl_divergence_to_be_less_than")
        # print(json.dumps(kl_divergence_evr, indent=2))
        if kl_divergence_evr is None or kl_divergence_evr.result is None or "details" not in kl_divergence_evr.result:
            return

        observed_partition_object = kl_divergence_evr.result["details"][
            "observed_partition"]
        weights = observed_partition_object["weights"]
        if len(weights) > 60:
            return None

        header = RenderedStringTemplateContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "Histogram",
                    "tooltip": {
                        "content":
                        "expect_column_kl_divergence_to_be_less_than"
                    },
                    "tag": "h6"
                }
            })

        return self._expectation_string_renderer._get_kl_divergence_chart(
            observed_partition_object, header)
Exemple #24
0
    def _render_header(cls, expectations):
        column = cls._get_column_name(expectations)

        new_block = RenderedHeaderContent(
            **{
                "header":
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": convert_to_string_and_escape(column),
                            "tag": "h5",
                            "styling": {
                                "classes": ["m-0"]
                            }
                        }
                    }),
                "styling": {
                    "classes": ["col-12"],
                    "header": {
                        "classes": ["alert", "alert-secondary"]
                    }
                }
            })

        return expectations, new_block
Exemple #25
0
    def _render_overview_table(self, evrs):
        unique_n = self._find_evr_by_type(
            evrs, "expect_column_unique_value_count_to_be_between")
        unique_proportion = self._find_evr_by_type(
            evrs, "expect_column_proportion_of_unique_values_to_be_between")
        null_evr = self._find_evr_by_type(
            evrs, "expect_column_values_to_not_be_null")
        evrs = [
            evr for evr in [unique_n, unique_proportion, null_evr]
            if (evr is not None)
        ]

        if len(evrs) > 0:
            new_content_block = self._overview_table_renderer.render(evrs)
            new_content_block.header = RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": 'Properties',
                        "tag": "h6"
                    }
                })
            new_content_block.styling = {
                "classes": ["col-3", "mt-1", "pl-1", "pr-1"],
                "body": {
                    "classes": ["table", "table-sm", "table-unbordered"],
                    "styles": {
                        "width": "100%"
                    },
                }
            }
            return new_content_block
Exemple #26
0
 def _descriptive_column_properties_table_distinct_count_row_renderer(
     cls,
     configuration=None,
     result=None,
     language=None,
     runtime_configuration=None,
     **kwargs,
 ):
     assert result, "Must pass in result."
     observed_value = result.result["observed_value"]
     template_string_object = RenderedStringTemplateContent(
         **{
             "content_block_type": "string_template",
             "string_template": {
                 "template": "Distinct (n)",
                 "tooltip": {
                     "content": "expect_column_unique_value_count_to_be_between"
                 },
             },
         }
     )
     if not observed_value:
         return [template_string_object, "--"]
     else:
         return [template_string_object, observed_value]
Exemple #27
0
    def _render_values_set(cls, evrs):
        set_evr = cls._find_evr_by_type(evrs, "expect_column_values_to_be_in_set")

        if not set_evr or set_evr.exception_info["raised_exception"]:
            return

        if set_evr and "partial_unexpected_counts" in set_evr.result:
            partial_unexpected_counts = set_evr.result["partial_unexpected_counts"]
            values = [str(v["value"]) for v in partial_unexpected_counts]
        elif set_evr and "partial_unexpected_list" in set_evr.result:
            values = [str(item) for item in set_evr.result["partial_unexpected_list"]]
        else:
            return

        classes = ["col-3", "mt-1", "pl-1", "pr-1"]

        if any(len(value) > 80 for value in values):
            content_block_type = "bullet_list"
            content_block_class = RenderedBulletListContent
        else:
            content_block_type = "value_list"
            content_block_class = ValueListContent

        new_block = content_block_class(
            **{
                "content_block_type": content_block_type,
                "header": RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "Example Values",
                            "tooltip": {"content": "expect_column_values_to_be_in_set"},
                            "tag": "h6",
                        },
                    }
                ),
                content_block_type: [
                    {
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "$value",
                            "params": {"value": value},
                            "styling": {
                                "default": {
                                    "classes": ["badge", "badge-info"]
                                    if content_block_type == "value_list"
                                    else [],
                                    "styles": {"word-break": "break-all"},
                                },
                            },
                        },
                    }
                    for value in values
                ],
                "styling": {"classes": classes,},
            }
        )

        return new_block
    def _render_validation_info(cls, 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:%SZ")
            except (ValueError, TypeError):
                run_time = "__none__"
            run_name = run_id
        elif isinstance(run_id, dict):
            run_name = run_id.get("run_name") or "__none__"
            try:
                run_time = str(
                    parse(
                        run_id.get("run_time")).strftime("%Y-%m-%dT%H:%M:%SZ"))
            except (ValueError, TypeError):
                run_time = "__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:%SZ")
        # TODO: Deprecate "great_expectations.__version__"
        ge_version = validation_results.meta.get(
            "great_expectations_version") or validation_results.meta.get(
                "great_expectations.__version__")

        return RenderedTableContent(
            **{
                "content_block_type":
                "table",
                "header":
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "Info",
                            "tag": "h6",
                            "styling": {
                                "classes": ["m-0"]
                            },
                        },
                    }),
                "table": [
                    ["Great Expectations Version", ge_version],
                    ["Run Name", run_name],
                    ["Run Time", run_time],
                ],
                "styling": {
                    "classes": ["col-12", "table-responsive", "mt-1"],
                    "body": {
                        "classes": ["table", "table-sm"],
                        "styles": {
                            "margin-bottom": "0.5rem !important",
                            "margin-top": "0.5rem !important",
                        },
                    },
                },
            })
Exemple #29
0
    def _render_quantile_table(cls, evrs):
        table_rows = []

        quantile_evr = cls._find_evr_by_type(
            evrs, "expect_column_quantile_values_to_be_between")

        if not quantile_evr or quantile_evr.exception_info["raised_exception"]:
            return

        quantiles = quantile_evr.result["observed_value"]["quantiles"]
        quantile_ranges = quantile_evr.result["observed_value"]["values"]

        quantile_strings = {.25: "Q1", .75: "Q3", .50: "Median"}

        for idx, quantile in enumerate(quantiles):
            quantile_string = quantile_strings.get(quantile)
            table_rows.append([
                {
                    "content_block_type": "string_template",
                    "string_template": {
                        "template":
                        quantile_string
                        if quantile_string else "{:3.2f}".format(quantile),
                        "tooltip": {
                            "content":
                            "expect_column_quantile_values_to_be_between \n expect_column_median_to_be_between"
                            if quantile == 0.50 else
                            "expect_column_quantile_values_to_be_between"
                        }
                    }
                },
                quantile_ranges[idx],
            ])

        return RenderedTableContent(
            **{
                "content_block_type":
                "table",
                "header":
                RenderedStringTemplateContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": 'Quantiles',
                            "tag": "h6"
                        }
                    }),
                "table":
                table_rows,
                "styling": {
                    "classes": ["col-3", "mt-1", "pl-1", "pr-1"],
                    "body": {
                        "classes": ["table", "table-sm", "table-unbordered"],
                    }
                },
            })
Exemple #30
0
    def _prescriptive_renderer(
        cls,
        configuration=None,
        result=None,
        language=None,
        runtime_configuration=None,
        **kwargs,
    ):
        runtime_configuration = runtime_configuration or {}
        include_column_name = runtime_configuration.get("include_column_name", True)
        include_column_name = (
            include_column_name if include_column_name is not None else True
        )
        styling = runtime_configuration.get("styling")
        params = substitute_none_for_missing(
            configuration.kwargs,
            ["column", "mostly", "row_condition", "condition_parser"],
        )

        if params["mostly"] is not None and params["mostly"] < 1.0:
            params["mostly_pct"] = num_to_str(
                params["mostly"] * 100, precision=15, no_scientific=True
            )
            # params["mostly_pct"] = "{:.14f}".format(params["mostly"]*100).rstrip("0").rstrip(".")
            if include_column_name:
                template_str = "$column values must not be null, at least $mostly_pct % of the time."
            else:
                template_str = (
                    "values must not be null, at least $mostly_pct % of the time."
                )
        else:
            if include_column_name:
                template_str = "$column values must never be null."
            else:
                template_str = "values must never be null."

        if params["row_condition"] is not None:
            (
                conditional_template_str,
                conditional_params,
            ) = parse_row_condition_string_pandas_engine(params["row_condition"])
            template_str = f"{conditional_template_str}, then {template_str}"
            params.update(conditional_params)

        return [
            RenderedStringTemplateContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": params,
                        "styling": styling,
                    },
                }
            )
        ]