Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ravi-kumar-pilla committed Nov 7, 2024
2 parents 57f6ddf + 02331cc commit b0a8575
Show file tree
Hide file tree
Showing 22 changed files with 408 additions and 52 deletions.
6 changes: 6 additions & 0 deletions README.npm.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ The example below demonstrates how to configure your kedro-viz using different `
tag: {
enabled: {companies: true}
},
behaviour: {
reFocus: true,
},
theme: "dark"
}}
/>
Expand All @@ -161,6 +164,9 @@ The example below demonstrates how to configure your kedro-viz using different `
| `sidebar` | boolean | true | Show/Hide Sidebar and action toolbar |
| `zoomToolbar` | boolean | true | Show/Hide zoom-in, zoom-out and zoom reset buttons together |
| options.expandAllPipelines | boolean | false | Expand/Collapse Modular pipelines on first load |
| options.behaviour | | | |
| `reFocus` | boolean | true | In the flowchart, enable or disable the node re-focus behavior when clicking on nodes.

| options.nodeType | `{disabled: {parameters: boolean,task: boolean,data: boolean}}` | `{disabled: {parameters: true,task: false,data: false}}` | Configuration for node type options |
| options.tag | `{enabled: {<tagName>: boolean}}` | - | Configuration for tag options |
| options.theme | string | dark | select `Kedro-Viz` theme : dark/light |
Expand Down
2 changes: 2 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Please follow the established format:
## Major features and improvements

- Update Kedro-Viz telemetry for opt-out model (#2022)
- Introduce `behaviour` prop object with `reFocus` prop (#2161)

## Bug fixes and other changes

- Improve `kedro viz build` usage documentation (#2126)
- Fix unserializable parameters value (#2122)
- Replace `watchgod` library with `watchfiles` and improve autoreload file watching filter (#2134)
- Display full dataset type with library prefix in metadata panel (#2136)
- Enable SQLite WAL mode for Azure ML to fix database locking issues (#2131)
- Replace `flake8`, `isort`, `pylint` and `black` by `ruff` (#2149)
Expand Down
12 changes: 8 additions & 4 deletions docs/source/kedro-viz_visualisation.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,25 @@ The visualisation now includes the layers:

## Share a pipeline visualisation

You can share a pipeline structure within a Kedro-Viz visualisation as a JSON file from the terminal:
You can save a pipeline structure within a Kedro-Viz visualisation directly from the terminal as follows:

```bash
kedro viz run --save-file=my_shareable_pipeline
```

This command will save a visualisation of the `__default__` pipeline as a JSON file called `my_shareable_pipeline.json`. It doesn't share data, such as that in the code panel, nor can you share images or charts.
This command saves your visualisation in a `my_shareable_pipeline` folder, which contains all pipeline and node information from your Kedro project.

To visualise the shared file, type the following to load it from the terminal:
To visualise your saved Kedro-Viz, load the `my_shareable_pipeline` folder from the terminal with:

```bash
kedro viz run --load-file=my_shareable_pipeline
```

You can also share a complete project visualisation, described in more detail on [the following page](./share_kedro_viz).
```{note}
This way of sharing requires a Kedro environment setup.
For users who prefer not to set up a Kedro environment, [Kedro-Viz visualisations can also be shared via multiple hosting solutions](./share_kedro_viz).
```

## Running Kedro-viz in a notebook.

Expand Down
3 changes: 2 additions & 1 deletion package/features/steps/lower_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fastapi==0.100.0
fsspec==2021.4
aiofiles==22.1.0
uvicorn[standard]==0.22.0
watchgod==0.8.2
watchfiles==0.24.0
plotly==4.8
packaging==23.0
pandas==1.3; python_version < '3.10'
Expand All @@ -16,3 +16,4 @@ secure==0.3.0
# numpy 2.0 breaks with old versions of pandas and this
# could be removed when the lowest version supported is updated
numpy==1.26.4
pathspec==0.12.1
88 changes: 88 additions & 0 deletions package/kedro_viz/autoreload_file_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
This module provides a custom file filter for autoreloading that filters out files based on allowed
file extensions and patterns specified in a .gitignore file.
"""

import logging
from pathlib import Path
from typing import Optional, Set

from pathspec import GitIgnoreSpec
from watchfiles import Change, DefaultFilter

logger = logging.getLogger(__name__)


class AutoreloadFileFilter(DefaultFilter):
"""
Custom file filter for autoreloading that extends DefaultFilter.
Filters out files based on allowed file extensions and patterns specified in a .gitignore file.
"""

allowed_extensions: Set[str] = {".py", ".yml", ".yaml", ".json"}

def __init__(self, base_path: Optional[Path] = None):
"""
Initialize the AutoreloadFileFilter.
Args:
base_path (Optional[Path]): The base path to set as the current working directory
for the filter.
"""
self.cwd = base_path or Path.cwd()

# Call the superclass constructor
super().__init__()

# Load .gitignore patterns
gitignore_path = self.cwd / ".gitignore"
try:
with open(gitignore_path, "r", encoding="utf-8") as gitignore_file:
ignore_patterns = gitignore_file.read().splitlines()
self.gitignore_spec: Optional[GitIgnoreSpec] = GitIgnoreSpec.from_lines(
"gitwildmatch", ignore_patterns
)
except FileNotFoundError:
self.gitignore_spec = None

def __call__(self, change: Change, path: str) -> bool:
"""
Determine whether a file change should be processed.
Args:
change (Change): The type of change detected.
path (str): The path to the file that changed.
Returns:
bool: True if the file should be processed, False otherwise.
"""
if not super().__call__(change, path):
logger.debug("Filtered out by DefaultFilter: %s", path)
return False

path_obj = Path(path)

# Exclude files matching .gitignore patterns
try:
relative_path = path_obj.resolve().relative_to(self.cwd.resolve())
except ValueError:
logger.debug("Path not relative to CWD: %s", path)
return False

try:
if self.gitignore_spec and self.gitignore_spec.match_file(
str(relative_path)
):
logger.debug("Filtered out by .gitignore: %s", relative_path)
return False
# ruff: noqa: BLE001
except Exception as exc:
logger.debug("Exception during .gitignore matching: %s", exc)
return True # Pass the file if .gitignore matching fails

# Include only files with allowed extensions
if path_obj.suffix in self.allowed_extensions:
logger.debug("Allowed file: %s", path)
return True
logger.debug("Filtered out by allowed_extensions: %s", path_obj.suffix)
return False
9 changes: 5 additions & 4 deletions package/kedro_viz/data_access/repositories/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ def __init__(self):
self.nodes_dict: Dict[str, GraphNode] = {}
self.nodes_list: List[GraphNode] = []

def has_node(self, node: GraphNode) -> bool:
return node.id in self.nodes_dict

def add_node(self, node: GraphNode) -> GraphNode:
if not self.has_node(node):
existing_node = self.nodes_dict.get(node.id)
if existing_node:
# Update tags or other attributes if the node already exists
existing_node.tags.update(node.tags)
else:
self.nodes_dict[node.id] = node
self.nodes_list.append(node)
return self.nodes_dict[node.id]
Expand Down
19 changes: 12 additions & 7 deletions package/kedro_viz/launchers/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from kedro.framework.cli.project import PARAMS_ARG_HELP
from kedro.framework.cli.utils import _split_params

from kedro_viz.autoreload_file_filter import AutoreloadFileFilter
from kedro_viz.constants import DEFAULT_HOST, DEFAULT_PORT
from kedro_viz.launchers.cli.main import viz

Expand Down Expand Up @@ -162,21 +163,25 @@ def run(
"extra_params": params,
"is_lite": lite,
}

process_context = multiprocessing.get_context("spawn")
if autoreload:
from watchgod import RegExpWatcher, run_process
from watchfiles import run_process

run_process_args = [str(kedro_project_path)]
run_process_kwargs = {
"path": kedro_project_path,
"target": run_server,
"kwargs": run_server_kwargs,
"watcher_cls": RegExpWatcher,
"watcher_kwargs": {"re_files": r"^.*(\.yml|\.yaml|\.py|\.json)$"},
"watch_filter": AutoreloadFileFilter(),
}
viz_process = multiprocessing.Process(
target=run_process, daemon=False, kwargs={**run_process_kwargs}
viz_process = process_context.Process(
target=run_process,
daemon=False,
args=run_process_args,
kwargs={**run_process_kwargs},
)
else:
viz_process = multiprocessing.Process(
viz_process = process_context.Process(
target=run_server, daemon=False, kwargs={**run_server_kwargs}
)

Expand Down
13 changes: 8 additions & 5 deletions package/kedro_viz/launchers/jupyter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
import IPython
from IPython.display import HTML, display
from kedro.framework.project import PACKAGE_NAME
from watchgod import RegExpWatcher, run_process
from watchfiles import run_process

from kedro_viz.autoreload_file_filter import AutoreloadFileFilter
from kedro_viz.launchers.utils import _check_viz_up, _wait_for
from kedro_viz.server import DEFAULT_HOST, DEFAULT_PORT, run_server

Expand Down Expand Up @@ -146,15 +147,17 @@ def run_viz(args: str = "", local_ns: Dict[str, Any] = None) -> None:
}
process_context = multiprocessing.get_context("spawn")
if autoreload:
run_process_args = [str(project_path)]
run_process_kwargs = {
"path": project_path,
"target": run_server,
"kwargs": run_server_kwargs,
"watcher_cls": RegExpWatcher,
"watcher_kwargs": {"re_files": r"^.*(\.yml|\.yaml|\.py|\.json)$"},
"watch_filter": AutoreloadFileFilter(),
}
viz_process = process_context.Process(
target=run_process, daemon=False, kwargs={**run_process_kwargs}
target=run_process,
daemon=False,
args=run_process_args,
kwargs={**run_process_kwargs},
)
else:
viz_process = process_context.Process(
Expand Down
17 changes: 11 additions & 6 deletions package/kedro_viz/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from kedro.io import DataCatalog
from kedro.pipeline import Pipeline

from kedro_viz.autoreload_file_filter import AutoreloadFileFilter
from kedro_viz.constants import DEFAULT_HOST, DEFAULT_PORT
from kedro_viz.data_access import DataAccessManager, data_access_manager
from kedro_viz.database import make_db_session_factory
Expand Down Expand Up @@ -143,7 +144,7 @@ def run_server(
import argparse
import multiprocessing

from watchgod import RegExpWatcher, run_process
from watchfiles import run_process

parser = argparse.ArgumentParser(description="Launch a development viz server")
parser.add_argument("project_path", help="Path to a Kedro project")
Expand All @@ -157,20 +158,24 @@ def run_server(

project_path = (Path.cwd() / args.project_path).absolute()

run_process_args = [str(project_path)]
run_process_kwargs = {
"path": project_path,
"target": run_server,
"kwargs": {
"host": args.host,
"port": args.port,
"project_path": str(project_path),
},
"watcher_cls": RegExpWatcher,
"watcher_kwargs": {"re_files": r"^.*(\.yml|\.yaml|\.py|\.json)$"},
"watch_filter": AutoreloadFileFilter(),
}

viz_process = multiprocessing.Process(
target=run_process, daemon=False, kwargs={**run_process_kwargs}
process_context = multiprocessing.get_context("spawn")

viz_process = process_context.Process(
target=run_process,
daemon=False,
args=run_process_args,
kwargs={**run_process_kwargs},
)

display_cli_message("Starting Kedro Viz ...", "green")
Expand Down
2 changes: 1 addition & 1 deletion package/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Tracker = "https://github.com/kedro-org/kedro-viz/issues"

[project.optional-dependencies]
docs = [
"kedro-sphinx-theme==2024.4.0",
"kedro-sphinx-theme==2024.10.2",
]
aws = ["s3fs>=2021.4"]
azure = ["adlfs>=2021.4"]
Expand Down
3 changes: 2 additions & 1 deletion package/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ secure>=0.3.0
sqlalchemy>=1.4, <3
strawberry-graphql>=0.192.0, <1.0
uvicorn[standard]>=0.30.0, <1.0
watchgod>=0.8.2, <1.0
watchfiles>=0.24.0
pathspec>=0.12.1
1 change: 1 addition & 0 deletions package/test_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ sqlalchemy-stubs~=0.4
strawberry-graphql[cli]>=0.99.0, <1.0
trufflehog~=2.2
httpx~=0.27.0
pathspec>=0.12.1

# mypy
types-aiofiles==0.1.3
Expand Down
Loading

0 comments on commit b0a8575

Please sign in to comment.