Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/new_renderer' into featu…
Browse files Browse the repository at this point in the history
…re/new_renderer
  • Loading branch information
jcampbell committed Jul 1, 2019
2 parents 878d6c5 + 121a28e commit 6c74c64
Show file tree
Hide file tree
Showing 37 changed files with 11,587 additions and 468 deletions.
40 changes: 19 additions & 21 deletions great_expectations/cli/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# -*- coding: utf-8 -*-

from .datasource import (
add_datasource
)
from .init import (
scaffold_directories_and_notebooks,
greeting_1,
msg_prompt_lets_begin,
)
from .util import cli_message
from great_expectations.render.view import DefaultJinjaPageView
from great_expectations.render.renderer import DescriptivePageRenderer, PrescriptivePageRenderer
from great_expectations.data_context import DataContext
from great_expectations.data_asset import FileDataAsset
from great_expectations.dataset import Dataset, PandasDataset
from great_expectations.exceptions import DataContextError
from great_expectations import __version__, read_csv
from pyfiglet import figlet_format
import click
import six
import os
Expand All @@ -9,35 +26,16 @@
import warnings
warnings.filterwarnings('ignore')

from pyfiglet import figlet_format
try:
from termcolor import colored
except ImportError:
colored = None

from great_expectations import __version__, read_csv
from great_expectations.exceptions import DataContextError
from great_expectations.dataset import Dataset, PandasDataset
from great_expectations.data_asset import FileDataAsset
from great_expectations.data_context import DataContext

from great_expectations.render.renderer import DescriptivePageRenderer, PrescriptivePageRenderer
from great_expectations.render.view import DescriptivePageView


from .util import cli_message
from .init import (
scaffold_directories_and_notebooks,
greeting_1,
msg_prompt_lets_begin,
)
from .datasource import (
add_datasource
)

# Take over the entire GE module logging namespace when running CLI
logger = logging.getLogger("great_expectations")


@click.group()
@click.version_option(version=__version__)
def cli():
Expand Down Expand Up @@ -187,7 +185,7 @@ def render(render_object):

model = DescriptivePageRenderer.render(raw)
# model = PrescriptivePageRenderer.render(raw)
print(DescriptivePageView.render(model))
print(DefaultJinjaPageView.render(model))


@cli.command()
Expand Down
25 changes: 14 additions & 11 deletions great_expectations/cli/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import click

from .util import cli_message
from great_expectations.render import DescriptivePageView
from great_expectations.render import DefaultJinjaPageView


def add_datasource(context):
Expand Down Expand Up @@ -42,7 +42,8 @@ def add_datasource(context):
show_default=True
)

context.add_datasource(data_source_name, "pandas", base_directory=os.path.join("..", path))
context.add_datasource(data_source_name, "pandas",
base_directory=os.path.join("..", path))

elif data_source_selection == "2": # sqlalchemy
data_source_name = click.prompt(
Expand Down Expand Up @@ -112,7 +113,7 @@ def add_datasource(context):
if data_source_name != None:

cli_message(
"""
"""
Would you like to profile '%s' to create candidate expectations and documentation?
Please note:
Expand All @@ -124,8 +125,8 @@ def add_datasource(context):
""" % (data_source_name)
)
if click.confirm("Proceed?",
default=True
):
default=True
):
profiling_results = context.profile_datasource(
data_source_name,
max_data_assets=20
Expand All @@ -137,10 +138,11 @@ def add_datasource(context):
expectation_suite_name = profiling_result[1]['meta']['expectation_suite_name']
run_id = profiling_result[1]['meta']['run_id']

print(" {0:s}".format(context.get_validation_location(data_asset_name, expectation_suite_name, run_id)['filepath']))
print(" {0:s}".format(context.get_validation_location(
data_asset_name, expectation_suite_name, run_id)['filepath']))

cli_message(
"""
"""
To generate documentation from the data you just profiled, the profiling results should be moved from
great_expectations/uncommitted (ignored by git) to great_expectations/fixtures. Before proceeding,
Expand All @@ -150,19 +152,20 @@ def add_datasource(context):
"""
)
if click.confirm("Proceed?",
default = True
):
default=True
):
cli_message("Rendering...")

for profiling_result in profiling_results:
data_asset_name = profiling_result[1]['meta']['data_asset_name']
expectation_suite_name = profiling_result[1]['meta']['expectation_suite_name']
run_id = profiling_result[1]['meta']['run_id']
context.move_validation_to_fixtures(data_asset_name, expectation_suite_name, run_id)
context.move_validation_to_fixtures(
data_asset_name, expectation_suite_name, run_id)

context.render_full_static_site()
cli_message(
"""
"""
To view the generated data documentation, start a web server:
<blue>cd great_expectations/data_documentation; python -m SimpleHTTPServer</blue> (if Python 2) or
<blue>cd great_expectations/data_documentation; python3 -m http.server</blue> (if Python 3)
Expand Down
4 changes: 2 additions & 2 deletions great_expectations/data_context/data_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
)
from great_expectations.profile.basic_dataset_profiler import BasicDatasetProfiler
from great_expectations.render.renderer import DescriptivePageRenderer, PrescriptivePageRenderer
from great_expectations.render.view import DescriptivePageView
from great_expectations.render.view import DefaultJinjaPageView


from .expectation_explorer import ExpectationExplorer
Expand Down Expand Up @@ -1233,7 +1233,7 @@ def render_full_static_site(self):
out_filepath = self.get_validation_doc_filepath(data_asset_name, expectation_suite_name)
safe_mmkdir(os.path.dirname(out_filepath))
with open(out_filepath, 'w') as writer:
writer.write(DescriptivePageView.render(model))
writer.write(DefaultJinjaPageView.render(model))

def profile_datasource(self, datasource_name, generator_name=None, profiler=BasicDatasetProfiler, max_data_assets=10):
logger.info("Profiling '%s' with '%s'" % (datasource_name, profiler.__name__))
Expand Down
2 changes: 1 addition & 1 deletion great_expectations/render/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .view import DescriptivePageView
from .view import DefaultJinjaPageView
34 changes: 17 additions & 17 deletions great_expectations/render/base.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
class Renderer(object):
# class Renderer(object):

@classmethod
def validate_input(cls, *args, **kwargs):
raise NotImplementedError
# @classmethod
# def validate_input(cls, *args, **kwargs):
# raise NotImplementedError

@classmethod
def _render_to_json(cls, *args, **kwargs):
raise NotImplementedError
# @classmethod
# def _render_to_json(cls, *args, **kwargs):
# raise NotImplementedError

@classmethod
def render(cls, *args, **kwargs):
raise NotImplementedError
# @classmethod
# def render(cls, *args, **kwargs):
# raise NotImplementedError

#!!! Move this out to view_model.__init__
# #!!! Move this out to view_model.__init__


class ViewModelRenderer(Renderer):
# class ViewModelRenderer(Renderer):

@classmethod
def render(cls, *args, **kwargs):
cls.validate_input(*args, **kwargs)
cls._render_to_json(*args, **kwargs)
raise NotImplementedError
# @classmethod
# def render(cls, *args, **kwargs):
# cls.validate_input(*args, **kwargs)
# cls._render_to_json(*args, **kwargs)
# raise NotImplementedError
62 changes: 39 additions & 23 deletions great_expectations/render/renderer/column_section_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from string import Template

from .renderer import Renderer
from .content_block import ValueListContentBlock
from .content_block import GraphContentBlock
from .content_block import TableContentBlock
from .content_block import BulletListContentBlock
from .content_block import ValueListContentBlockRenderer
from .content_block import GraphContentBlockRenderer
from .content_block import TableContentBlockRenderer
from .content_block import PrescriptiveBulletListContentBlockRenderer


class ColumnSectionRenderer(Renderer):
Expand Down Expand Up @@ -37,17 +37,16 @@ def render(cls, evrs, column=None):
if column is None:
column = cls._get_column_name(evrs)

content_blocks = {}
content_blocks = []
cls._render_header(evrs, column, content_blocks)
cls._render_column_type(evrs, content_blocks)
cls._render_overview_table(evrs, content_blocks)
cls._render_stats_table(evrs, content_blocks)
cls._render_values_set(evrs, content_blocks)
cls._render_unrecognized(evrs, content_blocks)


# FIXME: shown here as an example of bullet list
content_blocks["summary_list"] = {
content_blocks.append({
"content_block_type": "bullet_list",
"bullet_list": [
{
Expand All @@ -59,8 +58,7 @@ def render(cls, evrs, column=None):
"params": {}
}
]
}

})

return {
"section_name": column,
Expand All @@ -69,10 +67,10 @@ def render(cls, evrs, column=None):

@classmethod
def _render_header(cls, evrs, column_name, content_blocks):
content_blocks["header"] = {
content_blocks.append({
"content_block_type": "header",
"header": column_name,
}
})

@classmethod
def _render_column_type(cls, evrs, content_blocks):
Expand All @@ -89,7 +87,7 @@ def _render_column_type(cls, evrs, content_blocks):
"content_block_type": "text",
"content": [type_]
}
content_blocks["column_type"] = new_block
content_blocks.append(new_block)

@classmethod
def _render_overview_table(cls, evrs, content_blocks):
Expand All @@ -105,9 +103,12 @@ def _render_overview_table(cls, evrs, content_blocks):
evrs,
"expect_column_values_to_not_be_null"
)
evrs = [evr for evr in [unique_n, unique_proportion, null_evr] if evr is not None]
evrs = [evr for evr in [
unique_n, unique_proportion, null_evr] if evr is not None]
if len(evrs) > 0:
content_blocks["overview_table"] = TableContentBlock.render(evrs)
content_blocks.append(
TableContentBlockRenderer.render(evrs)
)

@classmethod
def _render_stats_table(cls, evrs, content_blocks):
Expand All @@ -125,7 +126,9 @@ def _render_stats_table(cls, evrs, content_blocks):
)
evrs = [evr for evr in [min_evr, mean_evr, max_evr] if evr is not None]
if len(evrs) > 0:
content_blocks["stats_table"] = TableContentBlock.render(evrs)
content_blocks.append(
TableContentBlockRenderer.render(evrs)
)

@classmethod
def _render_values_set(cls, evrs, content_blocks):
Expand All @@ -134,7 +137,7 @@ def _render_values_set(cls, evrs, content_blocks):
# Relatedly, this will change to grab values_list and to use expect_column_distinct_values_to_be_in_set
set_evr = cls._find_evr_by_type(
evrs,
"expect_column_values_to_be_in_set"
"expect_column_distinct_values_to_be_in_set"
)

if set_evr and "partial_unexpected_counts" in set_evr["result"]:
Expand All @@ -144,12 +147,20 @@ def _render_values_set(cls, evrs, content_blocks):
else:
return

if len(set_evr["result"][result_key]) > 10:
content_blocks["value_list"] = ValueListContentBlock.render(
set_evr, result_key=result_key)
if len(set_evr["result"][result_key]) < 10:
content_blocks.append(
ValueListContentBlockRenderer.render(
set_evr,
result_key=result_key
)
)
else:
content_blocks["value_graph"] = GraphContentBlock.render(
set_evr, result_key=result_key)
content_blocks.append(
GraphContentBlockRenderer.render(
set_evr,
result_key=result_key
)
)

@classmethod
def _render_unrecognized(cls, evrs, content_blocks):
Expand Down Expand Up @@ -180,7 +191,9 @@ def _render_unrecognized(cls, evrs, content_blocks):

if new_block is not None:
unrendered_blocks.append(new_block)
content_blocks["other_blocks"] = unrendered_blocks

# print(unrendered_blocks)
content_blocks += unrendered_blocks


class PrescriptiveColumnSectionRenderer(ColumnSectionRenderer):
Expand All @@ -198,7 +211,10 @@ def _render_header(cls, expectations, content_blocks):

@classmethod
def _render_bullet_list(cls, expectations, content_blocks):
content = BulletListContentBlock.render(expectations)
content = PrescriptiveBulletListContentBlockRenderer.render(
expectations,
include_column_name=False,
)
content_blocks.append(content)

return [], content_blocks
Expand Down
8 changes: 4 additions & 4 deletions great_expectations/render/renderer/content_block/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .value_list_content_block import ValueListContentBlock
from .table_content_block import TableContentBlock
from .graph_content_block import GraphContentBlock
from .bullet_list_content_block import BulletListContentBlock
from .value_list_content_block import ValueListContentBlockRenderer
from .table_content_block import TableContentBlockRenderer
from .graph_content_block import GraphContentBlockRenderer
from .bullet_list_content_block import PrescriptiveBulletListContentBlockRenderer
Loading

0 comments on commit 6c74c64

Please sign in to comment.