Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
40f9e05
init
safoinme Sep 27, 2025
cd81c4e
mypy
safoinme Sep 27, 2025
b420555
update sorting behavious
safoinme Sep 27, 2025
2014113
fix display order sorting
safoinme Sep 27, 2025
3376266
fixes
safoinme Sep 27, 2025
7139581
few more fixes
safoinme Sep 27, 2025
2ca3897
fix endpoint
safoinme Sep 27, 2025
1718b58
fix
safoinme Sep 29, 2025
4bc726a
docstring
safoinme Sep 29, 2025
e907e4f
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Sep 29, 2025
74002e7
add migrations file
safoinme Sep 29, 2025
43677a0
mypy
safoinme Sep 29, 2025
f05e1ee
Update visualization parameters to disable metadata and resources
safoinme Oct 5, 2025
6c09a15
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Oct 5, 2025
291c536
curated visualizations
safoinme Oct 9, 2025
c25ba31
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Oct 9, 2025
4d3f259
more fixes
safoinme Oct 11, 2025
98eb22c
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Oct 11, 2025
b4ae2d3
review fix and adding size
safoinme Oct 12, 2025
7f78e36
revert deloyment
safoinme Oct 13, 2025
2fc0553
add other schema support
safoinme Oct 13, 2025
f17f849
Rename 'size' to 'layout_size' in visualizations
safoinme Oct 13, 2025
2928bc0
Update src/zenml/models/v2/core/curated_visualization.py
safoinme Oct 14, 2025
f83b35e
Update src/zenml/models/v2/core/curated_visualization.py
safoinme Oct 14, 2025
318f5f5
renaming artifact_vertsion_id
safoinme Oct 14, 2025
347ac87
format
safoinme Oct 14, 2025
15b26c4
fix enum
safoinme Oct 14, 2025
5ba7c9e
apply stefan reviews
safoinme Oct 14, 2025
dae9fa5
delete migration outdated file
safoinme Oct 15, 2025
4166124
update migration file
safoinme Oct 15, 2025
978a1b0
docstring
safoinme Oct 15, 2025
22192c9
docstring
safoinme Oct 15, 2025
7d53da9
Update src/zenml/zen_stores/schemas/curated_visualization_schemas.py
safoinme Oct 15, 2025
e718e43
Update src/zenml/zen_stores/schemas/curated_visualization_schemas.py
safoinme Oct 15, 2025
176a838
Update src/zenml/models/v2/core/curated_visualization.py
safoinme Oct 15, 2025
6c7906b
Update src/zenml/models/v2/core/curated_visualization.py
safoinme Oct 15, 2025
b8ddcf9
Update src/zenml/zen_stores/schemas/pipeline_run_schemas.py
safoinme Oct 15, 2025
4e77acd
Merge branch 'feature/deployment-custom-visualizations' of https://gi…
safoinme Oct 15, 2025
efc8eff
final round of review
safoinme Oct 15, 2025
b4e7b44
docstring
safoinme Oct 15, 2025
2ded931
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Oct 15, 2025
24f920e
update migration
safoinme Oct 15, 2025
18fee07
Update src/zenml/zen_server/routers/curated_visualization_endpoints.py
safoinme Oct 16, 2025
ba3d5fb
Update src/zenml/zen_server/routers/curated_visualization_endpoints.py
safoinme Oct 16, 2025
960f354
Update src/zenml/zen_server/routers/curated_visualization_endpoints.py
safoinme Oct 16, 2025
c58b0b2
Update migration file description for visualizations
safoinme Oct 17, 2025
e827520
Merge branch 'develop' into feature/deployment-custom-visualizations
safoinme Oct 17, 2025
cfd35b0
renaming of visualisation
safoinme Oct 17, 2025
a41ffa1
migration
safoinme Oct 17, 2025
4a958d6
add model rebuild
safoinme Oct 17, 2025
edde4b6
update tests
safoinme Oct 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions src/zenml/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
ComponentUpdate,
DeploymentFilter,
DeploymentResponse,
DeploymentVisualizationFilter,
DeploymentVisualizationRequest,
DeploymentVisualizationResponse,
DeploymentVisualizationUpdate,
EventSourceFilter,
EventSourceRequest,
EventSourceResponse,
Expand Down Expand Up @@ -3735,6 +3739,127 @@ def get_deployment(
hydrate=hydrate,
)

def add_visualization_to_deployment(
self,
deployment_id: UUID,
artifact_version_id: UUID,
visualization_index: int,
*,
display_name: Optional[str] = None,
display_order: Optional[int] = None,
) -> DeploymentVisualizationResponse:
"""Curate a deployment visualization.

Args:
deployment_id: The ID of the deployment to add visualization to.
artifact_version_id: The ID of the artifact version containing the visualization.
visualization_index: The index of the visualization within the artifact version.
display_name: Optional display name for the visualization.
display_order: Optional display order for sorting visualizations.

Returns:
The created deployment visualization.
"""
deployment = self.get_deployment(deployment_id)
request = DeploymentVisualizationRequest(
project=deployment.project_id,
deployment_id=deployment_id,
artifact_version_id=artifact_version_id,
visualization_index=visualization_index,
display_name=display_name,
display_order=display_order,
)
return self.zen_store.create_deployment_visualization(request)

def list_deployment_visualizations(
self,
deployment_id: UUID,
*,
page: Optional[int] = None,
size: Optional[int] = None,
sort_by: Optional[str] = None,
visualization_index: Optional[int] = None,
hydrate: bool = False,
) -> Page[DeploymentVisualizationResponse]:
"""List curated deployment visualizations for a deployment.

Args:
deployment_id: The ID of the deployment to list visualizations for.
page: Page number for pagination.
size: Page size for pagination.
sort_by: Field to order by. Defaults to "display_order" in the filter.
visualization_index: Filter by visualization index. Must be non-negative.
hydrate: Flag deciding whether to hydrate the output model(s)
by including metadata fields in the response.

Returns:
A Page[DeploymentVisualizationResponse] containing the visualizations.

Raises:
ValueError: If visualization_index is negative.
"""
if visualization_index is not None and visualization_index < 0:
raise ValueError("visualization_index must be non-negative")

deployment = self.get_deployment(deployment_id)
filter_model = DeploymentVisualizationFilter(
project=deployment.project_id,
deployment=deployment_id,
)

# Only set optional filter params if provided, relying on filter defaults
if page is not None:
filter_model.page = page
if size is not None:
filter_model.size = size
if sort_by is not None:
filter_model.sort_by = sort_by
if visualization_index is not None:
filter_model.visualization_index = visualization_index

return self.zen_store.list_deployment_visualizations(
filter_model=filter_model,
hydrate=hydrate,
)

def update_deployment_visualization(
self,
deployment_visualization_id: UUID,
*,
display_name: Optional[str] = None,
display_order: Optional[int] = None,
) -> DeploymentVisualizationResponse:
"""Update display metadata for a curated deployment visualization.

Args:
deployment_visualization_id: The ID of the deployment visualization to update.
display_name: New display name for the visualization.
display_order: New display order for the visualization.

Returns:
The updated deployment visualization.
"""
update_model = DeploymentVisualizationUpdate(
display_name=display_name,
display_order=display_order,
)
return self.zen_store.update_deployment_visualization(
deployment_visualization_id=deployment_visualization_id,
visualization_update=update_model,
)

def delete_deployment_visualization(
self, deployment_visualization_id: UUID
) -> None:
"""Delete a curated deployment visualization.

Args:
deployment_visualization_id: The ID of the deployment visualization to delete.
"""
self.zen_store.delete_deployment_visualization(
deployment_visualization_id=deployment_visualization_id
)

def list_deployments(
self,
sort_by: str = "created",
Expand Down
1 change: 1 addition & 0 deletions src/zenml/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ def handle_int_env_var(var: str, default: int = 0) -> int:
PIPELINE_CONFIGURATION = "/pipeline-configuration"
PIPELINE_DEPLOYMENTS = "/pipeline_deployments"
DEPLOYMENTS = "/deployments"
DEPLOYMENT_VISUALIZATIONS = "/deployment_visualizations"
PIPELINE_SNAPSHOTS = "/pipeline_snapshots"
PIPELINES = "/pipelines"
PIPELINE_SPEC = "/pipeline-spec"
Expand Down
16 changes: 16 additions & 0 deletions src/zenml/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@
DeploymentResponseMetadata,
DeploymentResponseResources,
)
from zenml.models.v2.core.deployment_visualization import (
DeploymentVisualizationFilter,
DeploymentVisualizationRequest,
DeploymentVisualizationResponse,
DeploymentVisualizationResponseBody,
DeploymentVisualizationResponseMetadata,
DeploymentVisualizationResponseResources,
DeploymentVisualizationUpdate,
)
from zenml.models.v2.core.device import (
OAuthDeviceUpdate,
OAuthDeviceFilter,
Expand Down Expand Up @@ -653,6 +662,13 @@
"DeploymentResponseBody",
"DeploymentResponseMetadata",
"DeploymentResponseResources",
"DeploymentVisualizationFilter",
"DeploymentVisualizationRequest",
"DeploymentVisualizationResponse",
"DeploymentVisualizationResponseBody",
"DeploymentVisualizationResponseMetadata",
"DeploymentVisualizationResponseResources",
"DeploymentVisualizationUpdate",
"EventSourceFlavorResponse",
"EventSourceFlavorResponseBody",
"EventSourceFlavorResponseMetadata",
Expand Down
16 changes: 16 additions & 0 deletions src/zenml/models/v2/core/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
from sqlalchemy.sql.elements import ColumnElement

from zenml.models.v2.core.component import ComponentResponse
from zenml.models.v2.core.deployment_visualization import (
DeploymentVisualizationResponse,
)
from zenml.models.v2.core.pipeline import PipelineResponse
from zenml.models.v2.core.pipeline_snapshot import (
PipelineSnapshotResponse,
Expand Down Expand Up @@ -204,6 +207,10 @@ class DeploymentResponseResources(ProjectScopedResponseResources):
tags: List["TagResponse"] = Field(
title="Tags associated with the deployment.",
)
visualizations: List["DeploymentVisualizationResponse"] = Field(
default_factory=list,
title="Curated deployment visualizations.",
)


class DeploymentResponse(
Expand Down Expand Up @@ -304,6 +311,15 @@ def tags(self) -> List["TagResponse"]:
"""
return self.get_resources().tags

@property
def visualizations(self) -> List["DeploymentVisualizationResponse"]:
"""The visualizations of the deployment.

Returns:
The visualizations of the deployment.
"""
return self.get_resources().visualizations

@property
def snapshot_id(self) -> Optional[UUID]:
"""The pipeline snapshot ID.
Expand Down
Loading
Loading