Example #1
0
 def expect_column_values_to_not_be_null(cls, ge_object):
     return [[
         RenderedComponentContent(
             **{
                 "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 "--",
     ],
             [
                 RenderedComponentContent(
                     **{
                         "content_block_type": "string_template",
                         "string_template": {
                             "template": "Missing (%)",
                             "tooltip": {
                                 "content":
                                 "expect_column_values_to_not_be_null"
                             }
                         }
                     }),
                 "%.1f%%" %
                 (ge_object["result"]["unexpected_percent"] * 100.0)
                 if "unexpected_percent" in ge_object["result"]
                 and ge_object["result"]["unexpected_percent"] is not None
                 else "--",
             ]]
Example #2
0
    def _get_unexpected_statement(cls, evr):
        success = evr["success"]
        result = evr.get("result", {})

        if ("expectation_config" in evr and
                "exception_info" in evr and
                evr["exception_info"]["raised_exception"] is True):
            template_str = "\n\n$expectation_type raised an exception:\n$exception_message"

            return RenderedComponentContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": template_str,
                    "params": {
                        "expectation_type": evr["expectation_config"]["expectation_type"],
                        "exception_message": evr["exception_info"]["exception_message"]
                    },
                    "tag": "strong",
                    "styling": {
                        "classes": ["text-danger"],
                        "params": {
                            "exception_message": {
                                "tag": "code"
                            },
                            "expectation_type": {
                                "classes": ["badge", "badge-danger", "mb-2"]
                            }
                        }
                    }
                },
            })

        if success or not result.get("unexpected_count"):
            return None
        else:
            unexpected_count = result["unexpected_count"]
            unexpected_percent = "%.2f%%" % (result["unexpected_percent"])
            element_count = result["element_count"]
            
            template_str = "\n\n$unexpected_count unexpected values found. " \
                           "$unexpected_percent of $element_count total rows."

            return RenderedComponentContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": template_str,
                    "params": {
                        "unexpected_count": unexpected_count,
                        "unexpected_percent": unexpected_percent,
                        "element_count": element_count
                    },
                    "tag": "strong",
                    "styling": {
                        "classes": ["text-danger"]
                    }
                }
            })
Example #3
0
    def _render_dataset_info(cls, evrs, content_blocks):
        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([
            RenderedComponentContent(
                **{
                    "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"
                        }
                    }
                }),
            #??? : What is this?
            # "?" 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),
            ],  # "866 (8.1%)"
            # ["Duplicate rows", "0 (0.0%)", ], #TODO: bring back when we have an expectation for this
        ]

        content_blocks.append(
            RenderedComponentContent(
                **{
                    "content_block_type": "table",
                    "header": "Dataset info",
                    "table": table_rows,
                    "styling": {
                        "classes": ["col-6", "table-responsive"],
                        "styles": {
                            "margin-top": "20px"
                        },
                        "body": {
                            "classes": ["table", "table-sm"]
                        }
                    },
                }))
Example #4
0
    def _get_status_icon(cls, evr):
        if evr["exception_info"]["raised_exception"]:
            return RenderedComponentContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "$icon",
                    "params": {"icon": ""},
                    "styling": {
                        "params": {
                            "icon": {
                                "classes": ["fas", "fa-exclamation-triangle", "text-warning"],
                                "tag": "i"
                            }
                        }
                    }
                }
            })

        if evr["success"]:
            return RenderedComponentContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "$icon",
                    "params": {"icon": ""},
                    "styling": {
                        "params": {
                            "icon": {
                                "classes": ["fas", "fa-check-circle", "text-success"],
                                "tag": "i"
                            }
                        }
                    }
                }
            })
        else:
            return RenderedComponentContent(**{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "$icon",
                    "params": {"icon": ""},
                    "styling": {
                        "params": {
                            "icon": {
                                "tag": "i",
                                "classes": ["fas", "fa-times", "text-danger"]
                            }
                        }
                    }
                }
            })
Example #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 ("expectation_config" in evr and
                "exception_info" in evr and
                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 [RenderedComponentContent(**{
                "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,
                }
            })]
Example #6
0
 def _get_table_content_block(cls, header="", subheader="", col=12):
     return RenderedComponentContent(
         **{
             "content_block_type":
             "table",
             "header":
             header,
             "subheader":
             subheader,
             "table": [
                 ["", "column_1", "column_2"],
                 [
                     "row_1",
                     cls._get_bullet_list_content_block(
                         subheader="Nested Bullet List Content Block"),
                     "buffalo"
                 ],
                 ["row_2", "crayon", "derby"],
             ],
             "styling": {
                 "classes": ["col-{}".format(col), "table-responsive"],
                 "styles": {
                     "margin-top": "20px"
                 },
                 "body": {
                     "classes": ["table", "table-sm"]
                 }
             },
         })
Example #7
0
 def _get_value_list_content_block(cls, header="", subheader="", col=12):
     return RenderedComponentContent(
         **{
             "content_block_type":
             "value_list",
             "header":
             header,
             "subheader":
             subheader,
             "value_list": [{
                 "content_block_type": "string_template",
                 "string_template": {
                     "template": "$value",
                     "params": {
                         "value": value
                     },
                     "styling": {
                         "default": {
                             "classes": ["badge", "badge-info"],
                         },
                     }
                 }
             } for value in ["Andrew", "Elijah", "Matthew", "Cindy", "Pam"]
                            ],
             "styling": {
                 "classes": ["col-{}".format(col)]
             },
         })
Example #8
0
    def _render_variable_types(cls, evrs, content_blocks):

        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", "unknown"]]

        content_blocks.append(
            RenderedComponentContent(
                **{
                    "content_block_type": "table",
                    "header": "Variable types",
                    "table": table_rows,
                    "styling": {
                        "classes": [
                            "col-6",
                            "table-responsive",
                        ],
                        "styles": {
                            "margin-top": "20px"
                        },
                        "body": {
                            "classes": ["table", "table-sm"]
                        }
                    },
                }))
Example #9
0
def test_render_header_component():
    header_component_content = RenderedComponentContent(
        **{
            # "component_type": "header",
            "content_block_type": "header",
            "header": "Overview",
        })
    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": header_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == \
        """
<div id="section-1-content-block-2" >

    <div id="section-1-content-block-2-header" >
    <h3>
        Overview
    </h3></div>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
def test_render_value_list():
    value_list_component_content = RenderedComponentContent(**{
        'content_block_type': 'value_list',
        'header': 'Example values',
        'value_list': [{
            'content_block_type': 'string_template',
            'string_template': {
                'template': '$value',
                'params': {'value': '0'},
                'styling': {'default': {'classes': ['badge', 'badge-info']}}
            }
        }, {
            'content_block_type': 'string_template',
            'string_template': {
                'template': '$value',
                'params': {'value': '1'},
                'styling': {'default': {'classes': ['badge', 'badge-info']}}
            }
        }],
        'styling': {
            'classes': ['col-4'],
            'styles': {'margin-top': '20px'}
        }
    })

    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(**{
            "content_block": value_list_component_content,
            "section_loop": {"index": 1},
            "content_block_loop": {"index": 2},
        })
    )
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t", "").replace("\n", "")
    assert rendered_doc == """
<div id="section-1-content-block-2" class="col-4" style="margin-top:20px;" >

    <div id="section-1-content-block-2-header" >
        <h4>
            Example values
        </h4></div>


<p id="section-1-content-block-2-body" >
    
                <span >
                    <span class="badge badge-info" >0</span>
                </span>
            
    
                <span >
                    <span class="badge badge-info" >1</span>
                </span>
            
    </p>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
    def _get_unexpected_statement(cls, evr):
        success = evr["success"]
        try:
            result = evr["result"]
        except KeyError:
            return RenderedComponentContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": "Expectation failed to execute.",
                        "params": {},
                        "tag": "strong",
                        "styling": {
                            "classes": ["text-warning"]
                        }
                    }
                })

        if success or not result.get("unexpected_count"):
            return None
        else:
            unexpected_count = result["unexpected_count"]
            unexpected_percent = "%.2f%%" % (result["unexpected_percent"] *
                                             100.0)
            element_count = result["element_count"]

            template_str = "\n\n$unexpected_count unexpected values found. $unexpected_percent of $element_count total rows."

            return RenderedComponentContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": template_str,
                        "params": {
                            "unexpected_count": unexpected_count,
                            "unexpected_percent": unexpected_percent,
                            "element_count": element_count
                        },
                        "tag": "strong",
                        "styling": {
                            "classes": ["text-danger"]
                        }
                    }
                })
def test_ExpectationSuiteColumnSectionRenderer_render_header(
        titanic_profiled_name_column_expectations):
    remaining_expectations, content_blocks = ExpectationSuiteColumnSectionRenderer._render_header(
        titanic_profiled_name_column_expectations,  #["expectations"],
        [],
    )

    print(json.dumps(content_blocks, indent=2))
    assert content_blocks == [
        RenderedComponentContent(
            **{
                "content_block_type": "header",
                "header": "Name",
                "styling": {
                    "classes": ["col-12"],
                    "header": {
                        "classes": ["alert", "alert-secondary"]
                    }
                }
            })
    ]

    expectation_with_unescaped_dollar_sign = {
        "expectation_type": "expect_column_values_to_be_in_type_list",
        "kwargs": {
            "column":
            "Car Insurance Premiums ($)",
            "type_list": [
                "DOUBLE_PRECISION", "DoubleType", "FLOAT", "FLOAT4", "FLOAT8",
                "FloatType", "NUMERIC", "float"
            ],
            "result_format":
            "SUMMARY"
        },
        "meta": {
            "BasicDatasetProfiler": {
                "confidence": "very low"
            }
        }
    }
    remaining_expectations, content_blocks = ExpectationSuiteColumnSectionRenderer._render_header(
        [expectation_with_unescaped_dollar_sign], [])
    print(content_blocks)
    assert content_blocks[0] == {
        'content_block_type': 'header',
        'header': 'Car Insurance Premiums ($$)',
        'styling': {
            'classes': ['col-12'],
            'header': {
                'classes': ['alert', 'alert-secondary']
            }
        }
    }
def test_render_graph():
    graph_component_content = RenderedComponentContent(
        **{
            "content_block_type": "graph",
            "header": "Histogram",
            "graph":
            "{\"$schema\": \"https://vega.github.io/schema/vega-lite/v2.6.0.json\", \"autosize\": \"fit\", \"config\": {\"view\": {\"height\": 300, \"width\": 400}}, \"data\": {\"name\": \"data-a681d02fb484e64eadd9721b37015d5b\"}, \"datasets\": {\"data-a681d02fb484e64eadd9721b37015d5b\": [{\"bins\": 3.7, \"weights\": 5.555555555555555}, {\"bins\": 10.8, \"weights\": 3.439153439153439}, {\"bins\": 17.9, \"weights\": 17.857142857142858}, {\"bins\": 25.0, \"weights\": 24.206349206349206}, {\"bins\": 32.0, \"weights\": 16.137566137566136}, {\"bins\": 39.1, \"weights\": 12.3015873015873}, {\"bins\": 46.2, \"weights\": 9.788359788359788}, {\"bins\": 53.3, \"weights\": 5.423280423280423}, {\"bins\": 60.4, \"weights\": 3.439153439153439}, {\"bins\": 67.5, \"weights\": 1.8518518518518516}]}, \"encoding\": {\"x\": {\"field\": \"bins\", \"type\": \"ordinal\"}, \"y\": {\"field\": \"weights\", \"type\": \"quantitative\"}}, \"height\": 200, \"mark\": \"bar\", \"width\": 200}",
            "styling": {
                "classes": ["col-4"]
            }
        })

    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": graph_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == """
<div id="section-1-content-block-2" class="col-4" >

    <div id="section-1-content-block-2-header" >
        
        <h4>
            Histogram
        </h4>
        </div>
<div class="show-scrollbars">
  <div id="section-1-content-block-2-graph" ></div>
</div>
<script>
    // Assign the specification to a local variable vlSpec.
    vlSpec = {"$schema": "https://vega.github.io/schema/vega-lite/v2.6.0.json", "autosize": "fit", "config": {"view": {"height": 300, "width": 400}}, "data": {"name": "data-a681d02fb484e64eadd9721b37015d5b"}, "datasets": {"data-a681d02fb484e64eadd9721b37015d5b": [{"bins": 3.7, "weights": 5.555555555555555}, {"bins": 10.8, "weights": 3.439153439153439}, {"bins": 17.9, "weights": 17.857142857142858}, {"bins": 25.0, "weights": 24.206349206349206}, {"bins": 32.0, "weights": 16.137566137566136}, {"bins": 39.1, "weights": 12.3015873015873}, {"bins": 46.2, "weights": 9.788359788359788}, {"bins": 53.3, "weights": 5.423280423280423}, {"bins": 60.4, "weights": 3.439153439153439}, {"bins": 67.5, "weights": 1.8518518518518516}]}, "encoding": {"x": {"field": "bins", "type": "ordinal"}, "y": {"field": "weights", "type": "quantitative"}}, "height": 200, "mark": "bar", "width": 200};
    // Embed the visualization in the container with id `vis`
    vegaEmbed('#section-1-content-block-2-graph', vlSpec, {
        actions: false
    }).then(result=>console.log(result)).catch(console.warn);
</script>

</div>
""".replace(" ", "").replace("\t", "").replace("\n", "")
Example #14
0
 def _render_header(cls, evrs, content_blocks):
     content_blocks.append(
         RenderedComponentContent(
             **{
                 "content_block_type": "header",
                 "header": "Overview",
                 "styling": {
                     "classes": [
                         "col-12",
                     ],
                     "header": {
                         "classes": ["alert", "alert-secondary"]
                     }
                 }
             }))
Example #15
0
def test_render_table_component():
    table_component_content = RenderedComponentContent(
        **{
            # "component_type": "header",
            "content_block_type": "table",
            "header": "Overview",
            "table": [
                ["Mean", "446"],
                ["Minimum", "1"],
            ],
            "styling": {
                "classes": ["col-4"],
            }
        })
    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": table_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == \
        """
<div id="section-1-content-block-2" class="col-4" >

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


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

    <tr>
        <td id="section-1-content-block-2-cell-1-1" ><div class="table-cell-frame"><span>Mean</span></div></td><td id="section-1-content-block-2-cell-1-2" ><div class="table-cell-frame"><span>446</span></div></td></tr><tr>
        <td id="section-1-content-block-2-cell-2-1" ><div class="table-cell-frame"><span>Minimum</span></div></td><td id="section-1-content-block-2-cell-2-2" ><div class="table-cell-frame"><span>1</span></div></td></tr></table>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
Example #16
0
 def expect_column_unique_value_count_to_be_between(cls, ge_object):
     observed_value = ge_object["result"]["observed_value"]
     return [[
         RenderedComponentContent(
             **{
                 "content_block_type": "string_template",
                 "string_template": {
                     "template": "Distinct (n)",
                     "tooltip": {
                         "content":
                         "expect_column_unique_value_count_to_be_between"
                     }
                 }
             }),
         observed_value,
     ]]
Example #17
0
    def _get_unexpected_table(cls, evr):
        try:
            result = evr["result"]
        except KeyError:
            return None

        if not result.get("partial_unexpected_list") and not result.get(
                "partial_unexpected_counts"):
            return None

        table_rows = []

        if result.get("partial_unexpected_counts"):
            header_row = ["Unexpected Value", "Count"]
            for unexpected_count in result.get("partial_unexpected_counts"):
                if unexpected_count.get("value"):
                    table_rows.append([
                        unexpected_count.get("value"),
                        unexpected_count.get("count")
                    ])
                elif unexpected_count.get("value") == "":
                    table_rows.append(["EMPTY", unexpected_count.get("count")])
                else:
                    table_rows.append(["null", unexpected_count.get("count")])
        else:
            header_row = ["Unexpected Value"]
            for unexpected_value in result.get("partial_unexpected_list"):
                if unexpected_value:
                    table_rows.append([unexpected_value])
                elif unexpected_value == "":
                    table_rows.append(["EMPTY"])
                else:
                    table_rows.append(["null"])

        unexpected_table_content_block = RenderedComponentContent(
            **{
                "content_block_type": "table",
                "table": table_rows,
                "header_row": header_row,
                "styling": {
                    "body": {
                        "classes": ["table-bordered", "table-sm", "mt-3"]
                    }
                }
            })

        return unexpected_table_content_block
Example #18
0
 def _get_string_template_content_block(cls):
     return RenderedComponentContent(
         **{
             "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"
                 },
             },
         })
Example #19
0
 def _get_header_content_block(cls,
                               header="",
                               subheader="",
                               highlight=True):
     return RenderedComponentContent(
         **{
             "content_block_type": "header",
             "header": {
                 "template": header
             },
             "subheader": subheader,
             "styling": {
                 "classes": ["col-12"],
                 "header": {
                     "classes":
                     ["alert", "alert-secondary"] if highlight else []
                 }
             }
         })
Example #20
0
 def _get_tooltip_string_template_content_block(cls):
     return RenderedComponentContent(
         **{
             "content_block_type": "string_template",
             "string_template": {
                 "template":
                 "This is a string template with tooltip, using a top-level custom tag.",
                 "tag": "code",
                 "tooltip": {
                     "content": "This is the tooltip content."
                 }
             },
             "styling": {
                 "classes": ["col-12"],
                 "styles": {
                     "margin-top": "20px"
                 },
             },
         })
Example #21
0
 def expect_column_proportion_of_unique_values_to_be_between(
         cls, ge_object):
     observed_value = ge_object["result"]["observed_value"]
     template_string_object = RenderedComponentContent(
         **{
             "content_block_type": "string_template",
             "string_template": {
                 "template": "Distinct (%)",
                 "tooltip": {
                     "content":
                     "expect_column_proportion_of_unique_values_to_be_between"
                 }
             }
         })
     if not observed_value:
         return [[template_string_object, "--"]]
     else:
         return [[
             template_string_object,
             "%.1f%%" % (100 * observed_value)
         ]]
Example #22
0
 def _get_bullet_list_content_block(cls, header="", subheader="", col=12):
     return RenderedComponentContent(
         **{
             "content_block_type":
             "bullet_list",
             "header":
             header,
             "subheader":
             subheader,
             "bullet_list": [
                 "Aenean porttitor turpis.", "Curabitur ligula urna.",
                 cls._get_header_content_block(
                     header="nested header content block",
                     subheader="subheader",
                     highlight=False)
             ],
             "styling": {
                 "classes": ["col-{}".format(col)],
                 "styles": {
                     "margin-top": "20px"
                 },
             },
         })
Example #23
0
    def render(cls, ge_object, header_row=[]):
        """Each expectation method should return a list of rows"""
        if isinstance(ge_object, list):
            table_entries = []
            for sub_object in ge_object:
                expectation_type = cls._get_expectation_type(sub_object)
                extra_rows_fn = getattr(cls, expectation_type, None)
                if extra_rows_fn is not None:
                    rows = extra_rows_fn(sub_object)
                    table_entries.extend(rows)
        else:
            table_entries = []
            expectation_type = cls._get_expectation_type(ge_object)
            extra_rows_fn = getattr(cls, expectation_type, None)
            if extra_rows_fn is not None:
                rows = extra_rows_fn(ge_object)
                table_entries.extend(rows)

        return RenderedComponentContent(
            **{
                "content_block_type": "table",
                "header_row": header_row,
                "table": table_entries
            })
Example #24
0
    def _get_graph_content_block(cls, header="", subheader="", col=12):
        df = pd.DataFrame({
            "value": [1, 2, 3, 4, 5, 6],
            "count": [123, 232, 543, 234, 332, 888]
        })
        bars = alt.Chart(df).mark_bar(size=20).encode(
            y='count:Q', x="value:O").properties(height=200,
                                                 width=200,
                                                 autosize="fit")
        chart = bars.to_json()

        return RenderedComponentContent(
            **{
                "content_block_type": "graph",
                "header": header,
                "subheader": subheader,
                "graph": chart,
                "styling": {
                    "classes": ["col-{}".format(col)],
                    "styles": {
                        "margin-top": "20px"
                    },
                },
            })
Example #25
0
    def _render_expectation_types(cls, evrs, content_blocks):

        type_counts = defaultdict(int)

        for evr in evrs["results"]:
            type_counts[evr["expectation_config"]["expectation_type"]] += 1

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

        bullet_list = [
            RenderedComponentContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": "$expectation_type $expectation_count",
                        "params": {
                            "expectation_type": tr[0],
                            "expectation_count": tr[1],
                        },
                        "styling": {
                            "classes": [
                                "list-group-item", "d-flex",
                                "justify-content-between", "align-items-center"
                            ],
                            "params": {
                                "expectation_count": {
                                    "classes":
                                    ["badge", "badge-secondary", "badge-pill"],
                                }
                            }
                        }
                    }
                }) for tr in bullet_list
        ]

        content_blocks.append(
            RenderedComponentContent(
                **{
                    "content_block_type": "bullet_list",
                    "header":
                    'Expectation types <span class="mr-3 triangle"></span>',
                    "bullet_list": bullet_list,
                    "styling": {
                        "classes": ["col-12"],
                        "styles": {
                            "margin-top": "20px"
                        },
                        "header": {
                            "classes": ["collapsed"],
                            "attributes": {
                                "data-toggle": "collapse",
                                "href": "#{{content_block_id}}-body",
                                "aria-expanded": "true",
                                "aria-controls": "collapseExample",
                            },
                            "styles": {
                                "cursor": "pointer"
                            }
                        },
                        "body": {
                            "classes": ["list-group", "collapse"],
                        },
                    },
                }))
Example #26
0
def test_render_section_page():
    section = RenderedSectionContent(
        **{
            "section_name":
            None,
            "content_blocks": [
                RenderedComponentContent(**{
                    "content_block_type": "header",
                    "header": "Overview",
                }),
                RenderedComponentContent(
                    **{
                        "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.DefaultJinjaSectionView().render(
        RenderedComponentContentWrapper(**{
            "section": section,
            "section_loop": {
                "index": 1
            },
        }))  #.replace(" ", "").replace("\t", "").replace("\n", "")

    print(rendered_doc)

    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == """<div id="section-1" class="ge-section container-fluid">
    <div class="row">
        

<div id="content-block-1" >

    <div id="content-block-1-header" >
    <h3>
        Overview
    </h3></div>

</div>


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

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


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

    <tr>
        <td id="content-block-2-cell-1-1" ><div class="table-cell-frame"><span>Number of variables</span></div></td><td id="content-block-2-cell-1-2" ><div class="table-cell-frame"><span>12</span></div></td></tr><tr>
        <td id="content-block-2-cell-2-1" ><div class="table-cell-frame"><span>Number of observations</span></div></td><td id="content-block-2-cell-2-2" ><div class="table-cell-frame"><span>891</span></div></td></tr></table>

</div>
        
    </div>
</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
Example #27
0
def test_render_text():
    text_component_content = RenderedComponentContent(
        **{
            "content_block_type": "text",
            "header": "Histogram",
            "content": ["hello"],
            "styling": {
                "classes": ["col-4"]
            }
        })

    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": text_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == """
<div id="section-1-content-block-2" class="col-4" >

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


<div id="section-1-content-block-2-body" >
    <p>hello</p>
    </div>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")

    text_component_content = RenderedComponentContent(
        **{
            "content_block_type": "text",
            "header": "Histogram",
            "content": ["hello", "goodbye"],
            "styling": {
                "classes": ["col-4"]
            }
        })

    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": text_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")
    assert rendered_doc == """
<div id="section-1-content-block-2" class="col-4" >

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


<div id="section-1-content-block-2-body" >
    <p>hello</p>
    <p>goodbye</p>
    </div>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
Example #28
0
def test_rendering_components_with_styling():
    # Medium-complicated example to verify that all the things are correctly piped to all the places

    header_component_content = RenderedComponentContent(
        **{
            # "component_type": "table",
            "content_block_type": "table",
            "header": {
                "template": "$var1 $var2 $var3",
                "params": {
                    "var1": "AAA",
                    "var2": "BBB",
                    "var3": "CCC",
                },
                "styling": {
                    "default": {
                        "classes": ["x"]
                    },
                    "params": {
                        "var1": {
                            "classes": ["y"]
                        }
                    }
                }
            },
            "subheader": {
                "template": "$var1 $var2 $var3",
                "params": {
                    "var1": "aaa",
                    "var2": "bbb",
                    "var3": "ccc",
                },
                "styling": {
                    "default": {
                        "classes": ["xx"]
                    },
                    "params": {
                        "var1": {
                            "classes": ["yy"]
                        }
                    }
                }
            },
            "table": [
                ["Mean", "446"],
                ["Minimum", "1"],
            ],
            "styling": {
                "classes": ["root_foo"],
                "styles": {
                    "root": "bar"
                },
                "attributes": {
                    "root": "baz"
                },
                "header": {
                    "classes": ["header_foo"],
                    "styles": {
                        "header": "bar"
                    },
                    "attributes": {
                        "header": "baz"
                    },
                },
                "subheader": {
                    "classes": ["subheader_foo"],
                    "styles": {
                        "subheader": "bar"
                    },
                    "attributes": {
                        "subheader": "baz"
                    },
                },
                "body": {
                    "classes": ["body_foo"],
                    "styles": {
                        "body": "bar"
                    },
                    "attributes": {
                        "body": "baz"
                    },
                }
            }
        })
    rendered_doc = ge.render.view.view.DefaultJinjaComponentView().render(
        RenderedComponentContentWrapper(
            **{
                "content_block": header_component_content,
                "section_loop": {
                    "index": 1
                },
                "content_block_loop": {
                    "index": 2
                },
            }))
    print(rendered_doc)
    rendered_doc = rendered_doc.replace(" ", "").replace("\t",
                                                         "").replace("\n", "")

    assert rendered_doc == \
        """
<div id="section-1-content-block-2" class="root_foo" root="baz" style="root:bar;" >

    <div id="section-1-content-block-2-header" class="header_foo" header="baz" style="header:bar;" >
        
        <h4>
            
                <span >
                    <span class="y" >AAA</span> <span class="x" >BBB</span> <span class="x" >CCC</span>
                </span>
            
        </h4>
        <h5 id="section-1-content-block-2-subheader" class="subheader_foo" subheader="baz" style="subheader:bar;" >
            
                <span >
                    <span class="yy" >aaa</span> <span class="xx" >bbb</span> <span class="xx" >ccc</span>
                </span>
            
        </h5>
        </div>


<table id="section-1-content-block-2-body" class="body_foo" body="baz" style="body:bar;" >
    

    <tr>
        <td id="section-1-content-block-2-cell-1-1" ><div class="table-cell-frame"><span>Mean</span></div></td><td id="section-1-content-block-2-cell-1-2" ><div class="table-cell-frame"><span>446</span></div></td></tr><tr>
        <td id="section-1-content-block-2-cell-2-1" ><div class="table-cell-frame"><span>Minimum</span></div></td><td id="section-1-content-block-2-cell-2-2" ><div class="table-cell-frame"><span>1</span></div></td></tr></table>

</div>""".replace(" ", "").replace("\t", "").replace("\n", "")
    def _generate_data_asset_table_section(cls, data_asset_name,
                                           link_lists_dict):
        section_rows = []
        column_count = 1
        profiling_links = link_lists_dict["profiling_links"]
        if profiling_links: column_count += 1
        validation_links = link_lists_dict["validation_links"]
        if validation_links: column_count += 1
        expectation_suite_links = link_lists_dict["expectation_suite_links"]
        if expectation_suite_links: column_count += 1

        cell_width_pct = 100.0 / column_count

        first_row = []
        rowspan = str(
            len(expectation_suite_links)) if expectation_suite_links else "1"

        data_asset_name = RenderedComponentContent(
            **{
                "content_block_type": "string_template",
                "string_template": {
                    "template": "$data_asset",
                    "params": {
                        "data_asset": data_asset_name
                    },
                    "tag": "blockquote",
                    "styling": {
                        "params": {
                            "data_asset": {
                                "classes": ["blockquote"],
                            }
                        }
                    }
                },
                "styling": {
                    "classes": ["col-sm-3", "col-xs-12", "pl-sm-5", "pl-xs-0"],
                    "styles": {
                        "margin-top": "10px",
                        "word-break": "break-all"
                    },
                    "parent": {
                        "styles": {
                            "width": "{}%".format(cell_width_pct)
                        },
                        "attributes": {
                            "rowspan": rowspan
                        }
                    }
                }
            })
        first_row.append(data_asset_name)

        if profiling_links:
            profiling_results_bullets = [
                RenderedComponentContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "$link_text",
                            "params": {
                                "link_text":
                                link_dict["expectation_suite_name"] +
                                "-ProfilingResults"
                            },
                            "tag": "a",
                            "styling": {
                                "attributes": {
                                    "href": link_dict["filepath"]
                                }
                            }
                        }
                    }) for link_dict in profiling_links
            ]
            profiling_results_bullet_list = RenderedComponentContent(
                **{
                    "content_block_type": "bullet_list",
                    "bullet_list": profiling_results_bullets,
                    "styling": {
                        "parent": {
                            "styles": {
                                "width": "{}%".format(cell_width_pct),
                            },
                            "attributes": {
                                "rowspan": rowspan
                            }
                        }
                    }
                })
            first_row.append(profiling_results_bullet_list)

        if expectation_suite_links:
            expectation_suite_link_dict = expectation_suite_links[0]

            expectation_suite_name = expectation_suite_link_dict[
                "expectation_suite_name"]

            expectation_suite_link = RenderedComponentContent(
                **{
                    "content_block_type": "string_template",
                    "string_template": {
                        "template": "$link_text",
                        "params": {
                            "link_text": expectation_suite_name
                        },
                        "tag": "a",
                        "styling": {
                            "attributes": {
                                "href": expectation_suite_link_dict["filepath"]
                            },
                        }
                    },
                    "styling": {
                        "parent": {
                            "styles": {
                                "width": "{}%".format(cell_width_pct),
                            }
                        }
                    }
                })
            first_row.append(expectation_suite_link)

            if validation_links:
                validation_link_bullets = [
                    RenderedComponentContent(
                        **{
                            "content_block_type": "string_template",
                            "string_template": {
                                "template": "$link_text",
                                "params": {
                                    "link_text": link_dict["run_id"]
                                },
                                "tag": "a",
                                "styling": {
                                    "attributes": {
                                        "href": link_dict["filepath"]
                                    }
                                }
                            }
                        }) for link_dict in validation_links
                    if link_dict["expectation_suite_name"] ==
                    expectation_suite_name
                ]
                validation_link_bullet_list = RenderedComponentContent(
                    **{
                        "content_block_type": "bullet_list",
                        "bullet_list": validation_link_bullets,
                        "styling": {
                            "parent": {
                                "styles": {
                                    "width": "{}%".format(cell_width_pct)
                                }
                            },
                            "body": {
                                "styles": {
                                    "max-height": "15em",
                                    "overflow": "scroll"
                                }
                            }
                        }
                    })
                first_row.append(validation_link_bullet_list)

        if not expectation_suite_links and validation_links:
            validation_link_bullets = [
                RenderedComponentContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "$link_text",
                            "params": {
                                "link_text": link_dict["run_id"]
                            },
                            "tag": "a",
                            "styling": {
                                "attributes": {
                                    "href": link_dict["filepath"]
                                }
                            }
                        }
                    }) for link_dict in validation_links
            ]
            validation_link_bullet_list = RenderedComponentContent(
                **{
                    "content_block_type": "bullet_list",
                    "bullet_list": validation_link_bullets,
                    "styling": {
                        "parent": {
                            "styles": {
                                "width": "{}%".format(cell_width_pct)
                            }
                        },
                        "body": {
                            "styles": {
                                "max-height": "15em",
                                "overflow": "scroll"
                            }
                        }
                    }
                })
            first_row.append(validation_link_bullet_list)

        section_rows.append(first_row)

        if len(expectation_suite_links) > 1:
            for expectation_suite_link_dict in expectation_suite_links[1:]:
                expectation_suite_row = []
                expectation_suite_name = expectation_suite_link_dict[
                    "expectation_suite_name"]

                expectation_suite_link = RenderedComponentContent(
                    **{
                        "content_block_type": "string_template",
                        "string_template": {
                            "template": "$link_text",
                            "params": {
                                "link_text": expectation_suite_name
                            },
                            "tag": "a",
                            "styling": {
                                "attributes": {
                                    "href":
                                    expectation_suite_link_dict["filepath"]
                                },
                            }
                        },
                        "styling": {
                            "parent": {
                                "styles": {
                                    "width": "{}%".format(cell_width_pct),
                                }
                            }
                        }
                    })
                expectation_suite_row.append(expectation_suite_link)

                if validation_links:
                    validation_link_bullets = [
                        RenderedComponentContent(
                            **{
                                "content_block_type": "string_template",
                                "string_template": {
                                    "template": "$link_text",
                                    "params": {
                                        "link_text": link_dict["run_id"]
                                    },
                                    "tag": "a",
                                    "styling": {
                                        "attributes": {
                                            "href": link_dict["filepath"]
                                        }
                                    }
                                }
                            }) for link_dict in validation_links
                        if link_dict["expectation_suite_name"] ==
                        expectation_suite_name
                    ]
                    validation_link_bullet_list = RenderedComponentContent(
                        **{
                            "content_block_type": "bullet_list",
                            "bullet_list": validation_link_bullets,
                            "styling": {
                                "parent": {
                                    "styles": {
                                        "width": "{}%".format(cell_width_pct)
                                    }
                                },
                                "body": {
                                    "styles": {
                                        "max-height": "15em",
                                        "overflow": "scroll"
                                    }
                                }
                            }
                        })
                    expectation_suite_row.append(validation_link_bullet_list)

                section_rows.append(expectation_suite_row)

        return section_rows
    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
        })