def test_find_datasource_with_asset_on_context_with_no_datasources( empty_data_context, ): context = empty_data_context assert len(context.list_datasources()) == 0 renderer = CheckpointNewNotebookRenderer(context, "foo") obs = renderer._find_datasource_with_asset() assert obs is None
def test_find_datasource_with_asset_on_happy_path_context( deterministic_asset_dataconnector_context, ): context = deterministic_asset_dataconnector_context assert len(context.list_datasources()) == 1 renderer = CheckpointNewNotebookRenderer(context, "foo") obs = renderer._find_datasource_with_asset() assert obs == { "asset_name": "users", "data_connector_name": "my_other_data_connector", "datasource_name": "my_datasource", }
def test_render_checkpoint_new_notebook_with_available_data_asset( deterministic_asset_dataconnector_context, titanic_expectation_suite, checkpoint_new_notebook_assets, ): """ What does this test and why? The CheckpointNewNotebookRenderer should generate a notebook with an example SimpleCheckpoint yaml config based on the first available data asset. """ context: DataContext = deterministic_asset_dataconnector_context assert context.list_checkpoints() == [] context.save_expectation_suite(titanic_expectation_suite) assert context.list_expectation_suite_names() == ["Titanic.warning"] checkpoint_new_notebook_renderer = CheckpointNewNotebookRenderer( context=context, checkpoint_name="my_checkpoint_name" ) obs: nbformat.NotebookNode = checkpoint_new_notebook_renderer.render() assert isinstance(obs, dict) expected_cells = ( checkpoint_new_notebook_assets["header"] + checkpoint_new_notebook_assets["imports"] + checkpoint_new_notebook_assets[ "sample_checkpoint_config_markdown_description" ] # Testing to make sure everything in the notebook but especially this checkpoint config code is correct. + checkpoint_new_notebook_assets["sample_checkpoint_config_code_correct"] + checkpoint_new_notebook_assets["optional_customize_your_config"] + checkpoint_new_notebook_assets["test_and_save_your_checkpoint_configuration"] + checkpoint_new_notebook_assets["review_checkpoint"] + checkpoint_new_notebook_assets["add_checkpoint"] + checkpoint_new_notebook_assets["optional_run_checkpoint"] ) expected = { "nbformat": 4, "nbformat_minor": 4, "metadata": {}, "cells": expected_cells, } del expected["nbformat_minor"] del obs["nbformat_minor"] for obs_cell, expected_cell in zip(obs["cells"], expected["cells"]): obs_cell.pop("id", None) assert obs_cell == expected_cell assert obs == expected
def test_render_checkpoint_new_notebook_with_unavailable_data_asset( assetless_dataconnector_context, checkpoint_new_notebook_assets, ): context: DataContext = assetless_dataconnector_context assert context.list_checkpoints() == [] # This config is bad because of a missing expectation suite checkpoint_new_notebook_renderer = CheckpointNewNotebookRenderer( context=context, checkpoint_name="my_checkpoint_name" ) obs: nbformat.NotebookNode = checkpoint_new_notebook_renderer.render() assert isinstance(obs, dict) expected_cells = ( checkpoint_new_notebook_assets["header"] + checkpoint_new_notebook_assets["imports"] + checkpoint_new_notebook_assets[ "sample_checkpoint_config_markdown_description" ] # Testing to make sure the error message here is displayed appropriately + checkpoint_new_notebook_assets[ "sample_checkpoint_config_markdown_error_message" ] + checkpoint_new_notebook_assets["optional_customize_your_config"] + checkpoint_new_notebook_assets["test_and_save_your_checkpoint_configuration"] + checkpoint_new_notebook_assets["review_checkpoint"] + checkpoint_new_notebook_assets["add_checkpoint"] + checkpoint_new_notebook_assets["optional_run_checkpoint"] ) expected = { "nbformat": 4, "nbformat_minor": 4, "metadata": {}, "cells": expected_cells, } del expected["nbformat_minor"] del obs["nbformat_minor"] for obs_cell, expected_cell in zip(obs["cells"], expected["cells"]): obs_cell.pop("id", None) assert obs_cell == expected_cell assert obs == expected
def test_find_datasource_with_asset_on_context_with_a_datasource_with_a_dataconnector_that_has_no_assets( assetless_dataconnector_context, ): context = assetless_dataconnector_context assert list(context.get_datasource("my_datasource").data_connectors.keys()) == [ "my_other_data_connector" ] # remove data asset name config = context.get_config_with_variables_substituted() root_directory = context.root_directory context = BaseDataContext(project_config=config, context_root_dir=root_directory) renderer = CheckpointNewNotebookRenderer(context, "foo") obs = renderer._find_datasource_with_asset() assert obs is None
def _checkpoint_new(ctx, checkpoint_name, jupyter): context: DataContext = ctx.obj.data_context usage_event_end: str = ctx.obj.usage_event_end try: _verify_checkpoint_does_not_exist(context, checkpoint_name, usage_event_end) # Create notebook on disk notebook_name = f"edit_checkpoint_{checkpoint_name}.ipynb" notebook_file_path = _get_notebook_path(context, notebook_name) checkpoint_new_notebook_renderer = CheckpointNewNotebookRenderer( context=context, checkpoint_name=checkpoint_name ) checkpoint_new_notebook_renderer.render_to_disk( notebook_file_path=notebook_file_path ) if not jupyter: cli_message( f"To continue editing this Checkpoint, run <green>jupyter notebook {notebook_file_path}</green>" ) send_usage_message( data_context=context, event=usage_event_end, success=True, ) if jupyter: cli_message( """<green>Because you requested to create a new Checkpoint, we'll open a notebook for you now to edit it! If you wish to avoid this you can add the `--no-jupyter` flag.</green>\n\n""" ) toolkit.launch_jupyter_notebook(notebook_file_path) except Exception as e: toolkit.exit_with_failure_message_and_stats( data_context=context, usage_event=usage_event_end, message=f"<red>{e}</red>", ) return
def test_find_datasource_with_asset_on_context_with_a_datasource_with_no_dataconnectors( titanic_pandas_data_context_with_v013_datasource_stats_enabled_with_checkpoints_v1_with_templates, ): context = titanic_pandas_data_context_with_v013_datasource_stats_enabled_with_checkpoints_v1_with_templates context.delete_datasource("my_datasource") assert len(context.list_datasources()) == 0 context.add_datasource( "aaa_datasource", class_name="Datasource", module_name="great_expectations.datasource.new_datasource", execution_engine={ "class_name": "PandasExecutionEngine", "module_name": "great_expectations.execution_engine", }, ) assert len(context.list_datasources()) == 1 renderer = CheckpointNewNotebookRenderer(context, "foo") obs = renderer._find_datasource_with_asset() assert obs is None
def test_find_datasource_with_asset_on_context_with_a_full_datasource_and_one_with_no_dataconnectors( deterministic_asset_dataconnector_context, ): context = deterministic_asset_dataconnector_context assert len(context.list_datasources()) == 1 context.add_datasource( "aaa_datasource", class_name="Datasource", module_name="great_expectations.datasource.new_datasource", execution_engine={ "class_name": "PandasExecutionEngine", "module_name": "great_expectations.execution_engine", }, ) assert len(context.list_datasources()) == 2 renderer = CheckpointNewNotebookRenderer(context, "foo") obs = renderer._find_datasource_with_asset() assert obs == { "datasource_name": "my_datasource", "data_connector_name": "my_other_data_connector", "asset_name": "users", }