Skip to main content
Version: 0.14.13

How to add Statement Renderers for Custom Expectations

This guide will help you implement Statement RenderersA method for converting Expectations, Validation Results, etc. into Data Docs or other output such as email notifications or slack messages. for your Custom ExpectationsAn extension of the `Expectation` class, developed outside of the Great Expectations library..

Prerequisites: This how-to guide assumes you have:

We will add Statement Renderers to the Custom Expectations built in the guides for creating Custom Column Aggregate Expectations and creating Custom Column Map Expectations.

Great Expectations supports a number of Renderers, allowing you to control how your Custom Expectations are displayed in your Data DocsHuman readable documentation generated from Great Expectations metadata detailing Expectations, Validation Results, etc..

Implementing Renderers as part of your Custom Expectations is not strictly required - if not provided, Great Expectations will render your Custom Expectation using a basic default renderer:

Expectation rendered using default renderer

If you decide to contribute your ExpectationA verifiable assertion about data., its entry in the Expectations Gallery will reflect the Renderers that it supports.

Steps

1. Decide which renderer type to implement

There are two basic types of Statement Renderers:

  • renderer.prescriptive renders a human-readable form of your Custom Expectation
  • renderer.diagnostic renders diagnostic information about the results of your Custom Expectation

Prescriptive Renderers help provide clarity and structure in your Data Docs.

Diagnostic Renderers allow you to serve summary statistics, unexpected value samples, and observed values from your Custom Expectation, delivering further insights about your data.

But what do they look like?
There are several ways to implement Prescriptive and Diagnostic Renderers. The image below gives some examples of what these Renderers look like in action!

Annotated Validation Result Example

2. Declare the method for your Prescriptive Renderer


In general, Prescriptive Renderers receive an ExpectationConfiguration as input and return a list of rendered elements.

There are several ways to implement a Prescriptive Renderer. We're going to implement a String Template Renderer and a Table Renderer. Both of these implementations will share the @renderer(renderer_type="renderer.prescriptive) decorator, the @render_evaluation_parameter_string decorator, and the same initial method declaration. In our case, this looks like the following:

@renderer(renderer_type="render.prescriptive")
@render_evaluation_parameter_string
def _prescriptive_renderer(
cls,
configuration: ExpectationConfiguration = None,
result: ExpectationValidationResult = None,
language: str = None,
runtime_configuration: dict = None,
**kwargs,
):
assert (
configuration or result
), "Must provide renderers either a configuration or result."

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")
# get params dict with all expected kwargs
params = substitute_none_for_missing(
configuration.kwargs,
[
"column",
"min_value",
"max_value",
"mostly",
"row_condition",
"condition_parser",
"strict_min",
"strict_max",
],
)
note

While not strictly necessary for all Custom Expectations, adding the @render_evaluation_parameter_string decorator allows Expectations that use Evaluation Parameters to render the values of the Evaluation ParametersA dynamic value used during Validation of an Expectation which is populated by evaluating simple expressions or by referencing previously generated metrics. along with the rest of the output.

3. Implement the logic for your String Template Renderer


The String Template Prescriptive Renderer will render a semantic declaration of your Custom Expectation populated with the parameters your Custom Expectation requires.

note

The following example is being implemented in the Custom Expectation built in our guide on how to create Custom Column Aggregate Expectations.

To make this happen, we're going to build a template string based off of which parameters have been provided:

# build the string, parameter by parameter
if (params["min_value"] is None) and (params["max_value"] is None):
template_str = "maximum value may have any numerical value."
else:
at_least_str, at_most_str = handle_strict_min_max(params)

if params["min_value"] is not None and params["max_value"] is not None:
template_str = f"maximum value must be {at_least_str} $min_value and {at_most_str} $max_value."
elif params["min_value"] is None:
template_str = f"maximum value must be {at_most_str} $max_value."
elif params["max_value"] is None:
template_str = f"maximum value must be {at_least_str} $min_value."
else:
template_str = ""

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)

Then we return our string template, including the parameters that will populate and render it:

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

4. Verifying your implementation


If the core logic for your Custom Expectation is already complete, you can now utilize your Custom Expectation in an Expectation SuiteA collection of verifiable assertions about data. and ValidateThe act of applying an Expectation Suite to a Batch. against your data with a CheckpointThe primary means for validating data in a production deployment of Great Expectations., and see something similar to the following in your Data Docs:

String Template Example

If you have already implemented one of the Diagnostic Renderers covered elsewhere in this guide, you should now see the following when you call the print_diagnostic_checklist() method on your Custom Expectation:

✔ Has both Statement Renderers: prescriptive and diagnostic

Congratulations!
🎉 You've successfully implemented a Prescriptive Renderer for a Custom Expectation! 🎉

5. Contribution (Optional)

Renderers are not a requirement for for contribution back to Great Expectations at an Experimental level.

Implementing at least one Prescriptive and Diagnostic Renderer from this guide is required for contribution back to Great Expectations at a Beta or Production level.

If you believe your Custom Expectation is ready for contribution, please submit a Pull Request, and we will work with you to ensure your Custom Expectation meets these standards.

note

For more information on our code standards and contribution, see our guide on Levels of Maturity for Expectations.

To view the full scripts used in this page, see them on GitHub: