diff --git a/.github/actions/install_kedro_and_python_dependencies/action.yml b/.github/actions/install_kedro_and_python_dependencies/action.yml index 3874ccdc20..3d41b0da78 100644 --- a/.github/actions/install_kedro_and_python_dependencies/action.yml +++ b/.github/actions/install_kedro_and_python_dependencies/action.yml @@ -3,13 +3,17 @@ description: Installs Kedro from the main branch and other Python dependencies, runs: using: composite steps: - - name: Install Python dependencies - run: |- - pip install git+https://github.com/kedro-org/kedro@main - pip install -r package/test_requirements.txt -r demo-project/src/docker_requirements.txt -U - shell: bash - - name: Echo package versions - run: |- - python -V - pip freeze - shell: bash \ No newline at end of file + - name: Install `uv` + run: | + python -m pip install "uv==0.5.4" + shell: bash + - name: Install Python dependencies + run: |- + uv pip install --system git+https://github.com/kedro-org/kedro@main + uv pip install --system -r package/test_requirements.txt -r demo-project/src/docker_requirements.txt -U + shell: bash + - name: Echo package versions + run: |- + python -V + pip freeze + shell: bash diff --git a/RELEASE.md b/RELEASE.md index 0772ea0221..68e3f753fd 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,6 +6,15 @@ Please follow the established format: - Include the ID number for the related PR (or PRs) in parentheses --> +# Release 10.2.0 + + +## Major features and improvements + +## Bug fixes and other changes + +- Fix kedro viz `--load-file` to run from any directory without requiring a Kedro project. (#2206) + # Release 10.1.0 ## Major features and improvements @@ -17,6 +26,7 @@ Please follow the established format: ## Bug fixes and other changes + - Fix tag being undefined when pipeline are ordered differently (#2162, #2146) - Fix unserializable parameters value. (#2122) - Update kedro-viz lite banner icon and message. (#2196) diff --git a/docs/source/cli-docs.md b/docs/source/cli-docs.md index 72ea1b8af8..a4c3b95b70 100644 --- a/docs/source/cli-docs.md +++ b/docs/source/cli-docs.md @@ -44,10 +44,10 @@ kedro viz run [OPTIONS] - Whether to open the Kedro Viz interface in the default browser. The browser will open if the host is `localhost`. Defaults to `True`. - `--load-file ` - - Path to load Kedro Viz data from a directory. If provided, Kedro Viz will load the visualisation data from this path instead of generating it from the pipeline. + - Path to load Kedro Viz data from a [directory](#kedro-viz-directory-structure-when-you-save-it-as-a-file). If provided, Kedro Viz will load the visualisation data from this path instead of generating it from the pipeline - `--save-file ` - - Path to save Kedro Viz data to a directory. If provided, the visualisation data will be saved to this path for later use. + - Path to save Kedro Viz data to a [directory](#kedro-viz-directory-structure-when-you-save-it-as-a-file). If provided, the visualisation data will be saved to this path for later use. - `--pipeline, -p ` - Name of the registered pipeline to visualise. If not set, the default pipeline is visualised. @@ -162,4 +162,23 @@ kedro viz build --include-previews ``` +### Kedro-viz directory structure when you save it as a file + +When you use the `--save-file` option, Kedro Viz generates a directory structure to save the visualization data. This directory can later be used with the `--load-file` to reload the visualization. + +The generated directory structure looks like this: + +```bash +api/ +├── main # Main file containing pipeline structure +├── nodes/ +│ ├── node1 # JSON files for individual nodes +│ ├── node2 +│ └── ... +├── pipelines/ +│ ├── pipeline1 # JSON files for individual pipelines +│ ├── pipeline2 +│ └── ... +``` + diff --git a/docs/source/conf.py b/docs/source/conf.py index 20fa9b182f..b8ae078b77 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -54,7 +54,7 @@ exclude_patterns = [] source_suffix = {".rst": "restructuredtext", ".md": "markdown"} -myst_heading_anchors = 2 +myst_heading_anchors = 7 intersphinx_mapping = { "kedro": ("https://docs.kedro.org/en/stable/", None), diff --git a/docs/source/kedro-viz_visualisation.md b/docs/source/kedro-viz_visualisation.md index de4509e5b7..66c9cf651d 100644 --- a/docs/source/kedro-viz_visualisation.md +++ b/docs/source/kedro-viz_visualisation.md @@ -279,8 +279,8 @@ The `%run_viz` command supports various optional arguments found in `kedro viz r * `--host=`: Specify the server host. * `--port=`: Set the server port. -* `--load-file=`: Load a specific pipeline visualisation file. -* `--save-file=`: Save the current pipeline visualisation to a file. +* `--load-file=`: Load a specific pipeline visualisation from a [directory](./cli-docs.md#kedro-viz-directory-structure-when-you-save-it-as-a-file). +* `--save-file=`: Save the current pipeline visualisation to a [directory](./cli-docs.md#kedro-viz-directory-structure-when-you-save-it-as-a-file). * `--pipeline=`: Visualise a specific pipeline. * `--env=`: Set the environment for the visualisation. * `--autoreload`: Enable automatic reloading of the visualisation when source code changes. diff --git a/docs/source/preview_datasets.md b/docs/source/preview_datasets.md index 1d6b455e22..ec710208ce 100644 --- a/docs/source/preview_datasets.md +++ b/docs/source/preview_datasets.md @@ -29,7 +29,7 @@ See [Preview Matplotlib charts in Kedro-Viz](./preview_matplotlib_datasets.md) f **Extend Preview to custom catasets** -See [Extend Preview to custom catasets](./preview_custom_datasets.md) for a guide on how to set up previews for custom datasets and which types are supported by Kedro-Viz. +See [Extend Preview to custom datasets](./preview_custom_datasets.md) for a guide on how to set up previews for custom datasets and which types are supported by Kedro-Viz. ```{toctree} :maxdepth: 1 diff --git a/package/kedro_viz/launchers/cli/run.py b/package/kedro_viz/launchers/cli/run.py index e4093b940f..466d7f7aa8 100644 --- a/package/kedro_viz/launchers/cli/run.py +++ b/package/kedro_viz/launchers/cli/run.py @@ -123,16 +123,21 @@ def run( ) from kedro_viz.server import run_server - kedro_project_path = _find_kedro_project(Path.cwd()) - - if kedro_project_path is None: - display_cli_message( - "ERROR: Failed to start Kedro-Viz : " - "Could not find the project configuration " - f"file '{_PYPROJECT}' at '{Path.cwd()}'. ", - "red", - ) - return + kedro_project_path = None + + if load_file: + if not Path(load_file).exists(): + raise ValueError(f"The provided filepath '{load_file}' does not exist.") + else: + kedro_project_path = _find_kedro_project(Path.cwd()) + if kedro_project_path is None: + display_cli_message( + "ERROR: Failed to start Kedro-Viz : " + "Could not find the project configuration " + f"file '{_PYPROJECT}' at '{Path.cwd()}'. ", + "red", + ) + return installed_version = parse(__version__) latest_version = get_latest_version() diff --git a/package/kedro_viz/server.py b/package/kedro_viz/server.py index db95289b6d..8643bec73f 100644 --- a/package/kedro_viz/server.py +++ b/package/kedro_viz/server.py @@ -132,9 +132,6 @@ def run_server( app = apps.create_api_app_from_project(path, autoreload) else: - if not Path(load_file).exists(): - raise ValueError(f"The provided filepath '{load_file}' does not exist.") - app = apps.create_api_app_from_file(f"{path}/{load_file}/api") uvicorn.run(app, host=host, port=port, log_config=None) diff --git a/package/tests/test_launchers/test_cli/test_run.py b/package/tests/test_launchers/test_cli/test_run.py index 95a809d2ed..ccf579b0ff 100644 --- a/package/tests/test_launchers/test_cli/test_run.py +++ b/package/tests/test_launchers/test_cli/test_run.py @@ -1,3 +1,4 @@ +from pathlib import Path from unittest.mock import call import pytest @@ -411,3 +412,23 @@ def test_find_available_port_with_occupied_ports(self, mocker): assert ( available_port == 4143 ), "Expected port 4143 to be returned as the available port" + + +def test_invalid_load_file_directory(mocker): + """ + Test that Kedro-Viz raises a ValueError when an invalid filepath + is provided to the `--load-file` argument. + """ + runner = CliRunner() + + # Mock the existence of the file path to always return False (invalid path) + mocker.patch.object(Path, "exists", return_value=False) + + # Invoke the CLI with an invalid `--load-file` path + result = runner.invoke( + main.viz_cli, ["viz", "run", "--load-file", "nonexistent_path.json"] + ) + + assert "The provided filepath 'nonexistent_path.json' does not exist." == str( + result.exception + ) diff --git a/package/tests/test_server.py b/package/tests/test_server.py index 2169e9d4da..ca8d19a2c2 100644 --- a/package/tests/test_server.py +++ b/package/tests/test_server.py @@ -121,32 +121,15 @@ def test_specific_pipeline( {"data_science": example_pipelines["data_science"]} ) - @pytest.mark.parametrize( - "file_path, expected_exception", - [ - ("test.json", ValueError), # File does not exist, expect ValueError - ("test.json", None), # File exists, expect no ValueError - ], - ) - def test_load_file( - self, file_path, expected_exception, patched_create_api_app_from_file, tmp_path - ): - if expected_exception is not None: - with pytest.raises(expected_exception) as exc_info: - run_server(load_file=file_path) - - # Check if the error message contains the expected message - assert "The provided filepath" in str(exc_info.value) - assert "does not exist." in str(exc_info.value) - else: - json_file_path = tmp_path / file_path - - # File exists, no exception expected - with json_file_path.open("w") as file: - json.dump({"name": "John", "age": 30}, file) - - run_server(load_file=json_file_path) - patched_create_api_app_from_file.assert_called_once() + def test_load_file(self, patched_create_api_app_from_file, tmp_path): + file_path = "test.json" + json_file_path = tmp_path / file_path + + with json_file_path.open("w") as file: + json.dump({"name": "John", "age": 30}, file) + + run_server(load_file=json_file_path) + patched_create_api_app_from_file.assert_called_once() def test_save_file(self, tmp_path, mocker): mock_filesystem = mocker.patch("fsspec.filesystem")