def test_existing_local_data_docs_urls_returns_single_url_from_customized_local_site(
    tmp_path_factory, ):
    empty_directory = str(tmp_path_factory.mktemp("yo_yo"))
    DataContext.create(empty_directory)
    ge_dir = os.path.join(empty_directory, DataContext.GE_DIR)
    context = DataContext(ge_dir)

    context._project_config["data_docs_sites"] = {
        "my_rad_site": {
            "class_name": "SiteBuilder",
            "store_backend": {
                "class_name": "TupleFilesystemStoreBackend",
                "base_directory": "uncommitted/data_docs/some/local/path/",
            },
        }
    }

    # TODO Workaround project config programmatic config manipulation
    #  statefulness issues by writing to disk and re-upping a new context
    context._save_project_config()
    context = DataContext(ge_dir)
    context.build_data_docs()

    expected_path = os.path.join(
        ge_dir, "uncommitted/data_docs/some/local/path/index.html")
    assert os.path.isfile(expected_path)

    obs = context.get_docs_sites_urls()
    assert obs == [{
        "site_name": "my_rad_site",
        "site_url": "file://{}".format(expected_path)
    }]
コード例 #2
0
def test_docs_build_view(
        mock_webbrowser, caplog,
        site_builder_data_context_with_html_store_titanic_random):
    root_dir = site_builder_data_context_with_html_store_titanic_random.root_directory

    runner = CliRunner(mix_stderr=False)
    result = runner.invoke(cli, ["docs", "build", "-d", root_dir],
                           input="\n\n",
                           catch_exceptions=False)
    stdout = result.stdout

    assert result.exit_code == 0
    assert mock_webbrowser.call_count == 1
    assert "Building" in stdout
    assert "The following Data Docs sites will be built:" in stdout
    assert "great_expectations/uncommitted/data_docs/local_site/index.html" in stdout

    context = DataContext(root_dir)
    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 2
    assert ("great_expectations/uncommitted/data_docs/local_site/index.html"
            in obs_urls[0]["site_url"])
    local_site_dir = os.path.join(root_dir,
                                  "uncommitted/data_docs/local_site/")

    assert os.path.isdir(os.path.join(local_site_dir))
    assert os.path.isfile(os.path.join(local_site_dir, "index.html"))
    assert os.path.isdir(os.path.join(local_site_dir, "expectations"))
    assert os.path.isdir(os.path.join(local_site_dir, "validations"))
    assert_no_logging_messages_or_tracebacks(
        my_caplog=caplog,
        click_result=result,
    )
コード例 #3
0
def test_suite_demo_multiple_datasources_with_generator_with_suite_name_argument(
    mock_webbrowser,
    mock_subprocess,
    caplog,
    site_builder_data_context_with_html_store_titanic_random,
):
    """
    We call the "suite demo" command with the suite name argument

    - The data context has two datasources - we choose one of them.
    - It has a generator configured. We choose to use the generator and select
    a generator asset from the list.
    - open Data Docs
    - NOT open jupyter
    """
    root_dir = site_builder_data_context_with_html_store_titanic_random.root_directory
    os.chdir(root_dir)
    context = DataContext(root_dir)
    runner = CliRunner(mix_stderr=False)
    result = runner.invoke(
        cli,
        ["suite", "demo", "-d", root_dir, "--suite", "foo_suite"],
        input="2\n1\n1\n\n",
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert "Select a datasource" in stdout
    assert "Which data would you like to use" in stdout
    assert (
        "Great Expectations will choose a couple of columns and generate expectations"
        in stdout
    )
    assert "Generating example Expectation Suite..." in stdout
    assert "Building" in stdout
    assert "The following Data Docs sites were built" in stdout
    assert "A new Expectation suite 'foo_suite' was added to your project" in stdout

    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    assert (
        "great_expectations/uncommitted/data_docs/local_site/index.html"
        in obs_urls[0]["site_url"]
    )

    expected_index_path = os.path.join(
        root_dir, "uncommitted", "data_docs", "local_site", "index.html"
    )
    assert os.path.isfile(expected_index_path)

    expected_suite_path = os.path.join(root_dir, "expectations", "foo_suite.json")
    assert os.path.isfile(expected_suite_path)

    assert mock_webbrowser.call_count == 1
    assert mock_subprocess.call_count == 0

    assert_no_logging_messages_or_tracebacks(caplog, result)
コード例 #4
0
def test_suite_new_multiple_datasources_with_generator_without_suite_name_argument(
    caplog, site_builder_data_context_with_html_store_titanic_random,
):
    """
    We call the "suite new" command without the suite name argument

    The data context has two datasources - we choose one of them. It has a generator
    configured. We choose to use the generator and select a generator asset from the list.

    The command should prompt us to enter the name of the expectation suite that will be
    created.
    """
    root_dir = site_builder_data_context_with_html_store_titanic_random.root_directory
    os.chdir(root_dir)
    context = DataContext(root_dir)
    runner = CliRunner(mix_stderr=False)
    result = runner.invoke(
        cli,
        ["suite", "new", "-d", root_dir, "--no-view"],
        input="1\n1\n1\nmy_new_suite\n\n",
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert """Select a datasource
    1. random
    2. titanic""" in stdout
    assert """Which data would you like to use?
    1. f1 (file)
    2. f2 (file)""" in stdout
    assert "Name the new expectation suite [f1.warning]" in stdout
    assert (
        "Great Expectations will choose a couple of columns and generate expectations"
        in stdout
    )
    assert "Generating example Expectation Suite..." in stdout
    assert "Building" in stdout
    assert "The following Data Docs sites were built" in stdout
    assert "A new Expectation suite 'my_new_suite' was added to your project" in stdout

    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    assert (
        "great_expectations/uncommitted/data_docs/local_site/index.html" in obs_urls[0]
    )

    expected_index_path = os.path.join(
        root_dir, "uncommitted", "data_docs", "local_site", "index.html"
    )
    assert os.path.isfile(expected_index_path)

    expected_suite_path = os.path.join(root_dir, "expectations", "my_new_suite.json")
    assert os.path.isfile(expected_suite_path)
    assert_no_logging_messages_or_tracebacks(caplog, result)
def test_existing_local_data_docs_urls_returns_url_on_project_with_no_datasources_and_a_site_configured(
    tmp_path_factory, ):
    """
    This test ensures that a url will be returned for a default site even if a
    datasource is not configured, and docs are not built.
    """
    empty_directory = str(tmp_path_factory.mktemp("another_empty_project"))
    DataContext.create(empty_directory)
    context = DataContext(os.path.join(empty_directory, DataContext.GE_DIR))

    obs = context.get_docs_sites_urls(only_if_exists=False)
    assert len(obs) == 1
    assert obs[0]["site_url"].endswith(
        "great_expectations/uncommitted/data_docs/local_site/index.html")
コード例 #6
0
def test_docs_build_no_view(
    mock_webbrowser,
    caplog,
    monkeypatch,
    site_builder_data_context_v013_with_html_store_titanic_random,
):
    context = site_builder_data_context_v013_with_html_store_titanic_random
    root_dir = context.root_directory

    runner = CliRunner(mix_stderr=False)
    monkeypatch.chdir(os.path.dirname(context.root_directory))
    result = runner.invoke(
        cli,
        [
            "--v3-api",
            "docs",
            "build",
            "--no-view",
        ],
        input="\n",
        catch_exceptions=False,
    )
    stdout = result.stdout
    assert result.exit_code == 0
    assert mock_webbrowser.call_count == 0
    assert "Building" in stdout
    assert "The following Data Docs sites will be built:" in stdout
    assert "great_expectations/uncommitted/data_docs/local_site/index.html" in stdout

    context = DataContext(root_dir)
    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 2
    assert (
        "great_expectations/uncommitted/data_docs/local_site/index.html"
        in obs_urls[0]["site_url"]
    )
    local_site_dir = os.path.join(root_dir, "uncommitted/data_docs/local_site/")

    assert os.path.isdir(os.path.join(local_site_dir))
    assert os.path.isfile(os.path.join(local_site_dir, "index.html"))
    assert os.path.isdir(os.path.join(local_site_dir, "expectations"))
    assert os.path.isdir(os.path.join(local_site_dir, "validations"))
    assert_no_logging_messages_or_tracebacks(
        my_caplog=caplog,
        click_result=result,
        allowed_deprecation_message=VALIDATION_OPERATORS_DEPRECATION_MESSAGE,
    )
コード例 #7
0
def docs_list(directory):
    """List known Data Docs Sites."""
    context = None
    try:
        failed = True
        context = DataContext(directory)
        docs_sites_url_dicts = context.get_docs_sites_urls()
        docs_sites_strings = [
            " - <cyan>{}</cyan>: {}".format(docs_site_dict["site_name"], docs_site_dict["site_url"])\
            for docs_site_dict in docs_sites_url_dicts
        ]

        if len(docs_sites_strings) == 0:
            cli_message("No Data Docs sites found")
            failed = False
            send_usage_message(data_context=context,
                               event="cli.docs.list",
                               success=True)
            return

        if len(docs_sites_strings) == 1:
            list_intro_string = "1 Data Docs site found:"

        if len(docs_sites_strings) > 1:
            list_intro_string = "{} Data Docs sites found:".format(
                len(docs_sites_strings))
        cli_message_list(docs_sites_strings, list_intro_string)
        failed = False
        send_usage_message(data_context=context,
                           event="cli.docs.list",
                           success=True)
    except ge_exceptions.ConfigNotFoundError as err:
        cli_message("<red>{}</red>".format(err.message))
    finally:
        if failed and context is not None:
            send_usage_message(data_context=context,
                               event="cli.docs.list",
                               success=False)
コード例 #8
0
def test_suite_demo_one_datasource_without_generator_without_suite_name_argument(
    mock_webbrowser, mock_subprocess, caplog, empty_data_context, filesystem_csv_2
):
    """
    We call the "suite demo" command without the suite name argument

    The command should:

    - NOT prompt us to choose a datasource (because there is only one)
    - prompt us only to enter the path (The datasource has no generator
     configured and not to choose from the generator's list of available data
     assets).
    - We enter the path of the file we want the command to use as the batch to
    create the expectation suite.
    - prompt us to enter the name of the expectation suite that will be
    created
    - open Data Docs
    - NOT open jupyter
    """
    empty_data_context.add_datasource(
        "my_datasource",
        module_name="great_expectations.datasource",
        class_name="PandasDatasource",
    )

    context = empty_data_context
    root_dir = context.root_directory
    context = DataContext(root_dir)
    runner = CliRunner(mix_stderr=False)
    csv_path = os.path.join(filesystem_csv_2, "f1.csv")
    result = runner.invoke(
        cli,
        ["suite", "demo", "-d", root_dir],
        input=f"{csv_path}\nmy_new_suite\n\n",
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert "Enter the path" in stdout
    assert "Name the new Expectation Suite [f1.warning]" in stdout
    assert (
        "Great Expectations will choose a couple of columns and generate expectations"
        in stdout
    )
    assert (
        "Great Expectations will store these expectations in a new Expectation Suite 'my_new_suite' here:"
        in stdout
    )
    assert "Generating example Expectation Suite..." in stdout
    assert "Building" in stdout
    assert "The following Data Docs sites will be built" in stdout

    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    assert (
        "great_expectations/uncommitted/data_docs/local_site/index.html"
        in obs_urls[0]["site_url"]
    )

    expected_index_path = os.path.join(
        root_dir, "uncommitted", "data_docs", "local_site", "index.html"
    )
    assert os.path.isfile(expected_index_path)

    expected_suite_path = os.path.join(root_dir, "expectations", "my_new_suite.json")
    assert os.path.isfile(expected_suite_path)

    assert mock_webbrowser.call_count == 1
    assert mock_subprocess.call_count == 0

    assert_no_logging_messages_or_tracebacks(caplog, result)
コード例 #9
0
def test_suite_new_one_datasource_without_generator_without_suite_name_argument(
        caplog, empty_data_context, filesystem_csv_2):
    """
    We call the "suite new" command without the suite name argument

    The data context has one datasource, so the command does not prompt us to choose.
    The datasource has no generator configured, so we are prompted only to enter the path
    (and not to choose from the generator's list of available data assets).

    We enter the path of the file we want the command to use as the batch to create the
    expectation suite.

    The command should prompt us to enter the name of the expectation suite that will be
    created.
    """
    empty_data_context.add_datasource(
        "my_datasource",
        module_name="great_expectations.datasource",
        class_name="PandasDatasource",
    )

    not_so_empty_data_context = empty_data_context
    project_root_dir = not_so_empty_data_context.root_directory

    root_dir = project_root_dir
    os.chdir(root_dir)
    context = DataContext(root_dir)
    runner = CliRunner(mix_stderr=False)
    result = runner.invoke(
        cli,
        ["suite", "new", "-d", root_dir, "--no-view"],
        input="{0:s}\nmy_new_suite\n\n".format(
            os.path.join(filesystem_csv_2, "f1.csv")),
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert "Enter the path" in stdout
    assert "Name the new expectation suite [warning]" in stdout
    assert (
        "Great Expectations will choose a couple of columns and generate expectations"
        in stdout)
    assert "Generating example Expectation Suite..." in stdout
    assert "Building" in stdout
    assert "The following Data Docs sites were built" in stdout
    assert "A new Expectation suite 'my_new_suite' was added to your project" in stdout

    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    assert ("great_expectations/uncommitted/data_docs/local_site/index.html"
            in obs_urls[0])

    expected_index_path = os.path.join(root_dir, "uncommitted", "data_docs",
                                       "local_site", "index.html")
    assert os.path.isfile(expected_index_path)

    expected_suite_path = os.path.join(root_dir, "expectations",
                                       "my_new_suite.json")
    assert os.path.isfile(expected_suite_path)
    assert_no_logging_messages_or_tracebacks(caplog, result)
コード例 #10
0
def test_docs_build_view(
    mock_webbrowser,
    mock_emit,
    caplog,
    monkeypatch,
    titanic_data_context_stats_enabled_config_version_3,
):
    context = titanic_data_context_stats_enabled_config_version_3
    root_dir = context.root_directory

    runner = CliRunner(mix_stderr=False)
    monkeypatch.chdir(os.path.dirname(context.root_directory))
    result = runner.invoke(
        cli,
        "--v3-api docs build",
        input="\n",
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert mock_webbrowser.call_count == 1
    assert "Would you like to proceed?" in stdout
    assert "Building" in stdout
    assert "The following Data Docs sites will be built:" in stdout
    assert "local_site" in stdout
    assert "great_expectations/uncommitted/data_docs/local_site/index.html" in stdout

    assert mock_emit.call_count == 4
    assert mock_emit.call_args_list == [
        mock.call({
            "event_payload": {},
            "event": "data_context.__init__",
            "success": True
        }),
        mock.call({
            "event_payload": {},
            "event": "data_context.build_data_docs",
            "success": True,
        }),
        mock.call({
            "event_payload": {},
            "event": "data_context.open_data_docs",
            "success": True,
        }),
        mock.call({
            "event": "cli.docs.build",
            "event_payload": {
                "api_version": "v3"
            },
            "success": True,
        }),
    ]

    context = DataContext(root_dir)
    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    assert ("great_expectations/uncommitted/data_docs/local_site/index.html"
            in obs_urls[0]["site_url"])
    site_dir = os.path.join(root_dir, context.GE_UNCOMMITTED_DIR, "data_docs",
                            "local_site")
    assert os.path.isdir(site_dir)
    # Note the fixture has no expectations or validations - only check the index
    assert os.path.isfile(os.path.join(site_dir, "index.html"))

    assert_no_logging_messages_or_tracebacks(
        my_caplog=caplog,
        click_result=result,
    )
コード例 #11
0
def test_docs_build_happy_paths_build_site_on_single_site_context(
    mock_webbrowser,
    mock_emit,
    invocation,
    cli_input,
    expected_stdout,
    expected_browser_call_count,
    caplog,
    monkeypatch,
    titanic_data_context_stats_enabled_config_version_3,
):
    context = titanic_data_context_stats_enabled_config_version_3
    root_dir = context.root_directory
    runner = CliRunner(mix_stderr=False)
    monkeypatch.chdir(os.path.dirname(context.root_directory))
    result = runner.invoke(
        cli,
        invocation,
        input=cli_input,
        catch_exceptions=False,
    )
    stdout = result.stdout

    assert result.exit_code == 0
    assert "The following Data Docs sites will be built" in stdout
    assert "local_site" in stdout
    if not cli_input == "n\n":
        assert "Building Data Docs..." in stdout
        assert "Done building Data Docs" in stdout
    assert expected_stdout in stdout
    assert mock_webbrowser.call_count == expected_browser_call_count

    expected_usage_stats_messages = [
        mock.call({
            "event_payload": {},
            "event": "data_context.__init__",
            "success": True
        }),
        mock.call({
            "event": "cli.docs.build.begin",
            "event_payload": {
                "api_version": "v3"
            },
            "success": True,
        }),
    ]
    if not cli_input == "n\n":
        expected_usage_stats_messages.append(
            mock.call({
                "event_payload": {},
                "event": "data_context.build_data_docs",
                "success": True,
            }), )
    if expected_browser_call_count == 1:
        expected_usage_stats_messages.append(
            mock.call({
                "event_payload": {},
                "event": "data_context.open_data_docs",
                "success": True,
            }), )
    build_docs_end_event_payload = {"api_version": "v3"}
    if cli_input == "n\n":
        build_docs_end_event_payload.update({"cancelled": True})
    expected_usage_stats_messages.append(
        mock.call({
            "event": "cli.docs.build.end",
            "event_payload": build_docs_end_event_payload,
            "success": True,
        }), )
    assert mock_emit.call_args_list == expected_usage_stats_messages

    context = DataContext(root_dir)
    obs_urls = context.get_docs_sites_urls()

    assert len(obs_urls) == 1
    if not cli_input == "n\n":
        assert (
            "great_expectations/uncommitted/data_docs/local_site/index.html"
            in obs_urls[0]["site_url"])
        site_dir = os.path.join(root_dir, context.GE_UNCOMMITTED_DIR,
                                "data_docs", "local_site")
        assert os.path.isdir(site_dir)
        # Note the fixture has no expectations or validations - only check the index
        assert os.path.isfile(os.path.join(site_dir, "index.html"))

    assert_no_logging_messages_or_tracebacks(
        my_caplog=caplog,
        click_result=result,
    )