zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250314__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zenml/VERSION +1 -1
- zenml/__init__.py +2 -0
- zenml/analytics/context.py +7 -0
- zenml/analytics/enums.py +2 -2
- zenml/artifacts/utils.py +2 -4
- zenml/cli/__init__.py +8 -9
- zenml/cli/base.py +2 -2
- zenml/cli/code_repository.py +1 -1
- zenml/cli/login.py +6 -0
- zenml/cli/model.py +7 -15
- zenml/cli/pipeline.py +3 -3
- zenml/cli/project.py +172 -0
- zenml/cli/secret.py +47 -44
- zenml/cli/service_accounts.py +0 -1
- zenml/cli/service_connectors.py +15 -17
- zenml/cli/stack.py +0 -3
- zenml/cli/stack_components.py +2 -2
- zenml/cli/tag.py +3 -5
- zenml/cli/utils.py +25 -23
- zenml/client.py +749 -475
- zenml/config/global_config.py +48 -37
- zenml/config/pipeline_configurations.py +3 -2
- zenml/config/pipeline_run_configuration.py +2 -1
- zenml/config/secret_reference_mixin.py +1 -1
- zenml/constants.py +6 -6
- zenml/enums.py +0 -7
- zenml/event_hub/event_hub.py +3 -1
- zenml/exceptions.py +0 -24
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +7 -6
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
- zenml/integrations/mlflow/steps/mlflow_registry.py +3 -3
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
- zenml/integrations/wandb/__init__.py +1 -1
- zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py +29 -9
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +5 -3
- zenml/model/model.py +10 -10
- zenml/model_registries/base_model_registry.py +1 -1
- zenml/models/__init__.py +45 -28
- zenml/models/v2/base/base.py +0 -5
- zenml/models/v2/base/filter.py +2 -2
- zenml/models/v2/base/scoped.py +135 -156
- zenml/models/v2/core/action.py +12 -12
- zenml/models/v2/core/api_key.py +1 -1
- zenml/models/v2/core/artifact.py +31 -18
- zenml/models/v2/core/artifact_version.py +57 -40
- zenml/models/v2/core/code_repository.py +12 -12
- zenml/models/v2/core/component.py +22 -33
- zenml/models/v2/core/device.py +3 -2
- zenml/models/v2/core/event_source.py +14 -14
- zenml/models/v2/core/flavor.py +19 -47
- zenml/models/v2/core/logs.py +1 -2
- zenml/models/v2/core/model.py +23 -20
- zenml/models/v2/core/model_version.py +51 -42
- zenml/models/v2/core/pipeline.py +16 -16
- zenml/models/v2/core/pipeline_build.py +14 -14
- zenml/models/v2/core/pipeline_deployment.py +12 -14
- zenml/models/v2/core/pipeline_run.py +21 -29
- zenml/models/v2/core/project.py +203 -0
- zenml/models/v2/core/run_metadata.py +2 -2
- zenml/models/v2/core/run_template.py +16 -17
- zenml/models/v2/core/schedule.py +12 -21
- zenml/models/v2/core/secret.py +94 -128
- zenml/models/v2/core/server_settings.py +2 -2
- zenml/models/v2/core/service.py +57 -26
- zenml/models/v2/core/service_connector.py +14 -16
- zenml/models/v2/core/stack.py +24 -26
- zenml/models/v2/core/step_run.py +16 -28
- zenml/models/v2/core/tag.py +41 -15
- zenml/models/v2/core/trigger.py +13 -13
- zenml/models/v2/core/trigger_execution.py +2 -2
- zenml/models/v2/core/user.py +2 -2
- zenml/models/v2/misc/statistics.py +45 -0
- zenml/models/v2/misc/tag.py +27 -0
- zenml/orchestrators/cache_utils.py +7 -7
- zenml/orchestrators/input_utils.py +1 -0
- zenml/orchestrators/step_launcher.py +1 -2
- zenml/orchestrators/step_run_utils.py +2 -4
- zenml/orchestrators/step_runner.py +10 -1
- zenml/orchestrators/utils.py +4 -4
- zenml/pipelines/build_utils.py +2 -4
- zenml/pipelines/pipeline_decorator.py +3 -2
- zenml/pipelines/pipeline_definition.py +8 -9
- zenml/pipelines/run_utils.py +4 -4
- zenml/service_connectors/service_connector.py +0 -10
- zenml/service_connectors/service_connector_utils.py +0 -2
- zenml/stack/authentication_mixin.py +1 -1
- zenml/stack/flavor.py +3 -14
- zenml/stack/stack.py +0 -1
- zenml/stack/stack_component.py +1 -5
- zenml/steps/base_step.py +10 -2
- zenml/steps/step_context.py +19 -0
- zenml/utils/string_utils.py +1 -1
- zenml/utils/tag_utils.py +642 -0
- zenml/zen_server/cloud_utils.py +21 -0
- zenml/zen_server/exceptions.py +0 -6
- zenml/zen_server/rbac/endpoint_utils.py +134 -46
- zenml/zen_server/rbac/models.py +65 -3
- zenml/zen_server/rbac/rbac_interface.py +9 -0
- zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
- zenml/zen_server/rbac/utils.py +155 -30
- zenml/zen_server/rbac/zenml_cloud_rbac.py +39 -11
- zenml/zen_server/routers/actions_endpoints.py +3 -5
- zenml/zen_server/routers/artifact_endpoint.py +0 -5
- zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
- zenml/zen_server/routers/auth_endpoints.py +22 -7
- zenml/zen_server/routers/code_repositories_endpoints.py +54 -3
- zenml/zen_server/routers/devices_endpoints.py +0 -4
- zenml/zen_server/routers/event_source_endpoints.py +0 -5
- zenml/zen_server/routers/flavors_endpoints.py +0 -5
- zenml/zen_server/routers/logs_endpoints.py +0 -1
- zenml/zen_server/routers/model_versions_endpoints.py +100 -23
- zenml/zen_server/routers/models_endpoints.py +50 -69
- zenml/zen_server/routers/pipeline_builds_endpoints.py +55 -3
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +56 -4
- zenml/zen_server/routers/pipelines_endpoints.py +70 -3
- zenml/zen_server/routers/plugin_endpoints.py +0 -1
- zenml/zen_server/routers/projects_endpoints.py +283 -0
- zenml/zen_server/routers/run_metadata_endpoints.py +97 -0
- zenml/zen_server/routers/run_templates_endpoints.py +64 -3
- zenml/zen_server/routers/runs_endpoints.py +58 -8
- zenml/zen_server/routers/schedule_endpoints.py +67 -6
- zenml/zen_server/routers/secrets_endpoints.py +38 -4
- zenml/zen_server/routers/server_endpoints.py +53 -1
- zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
- zenml/zen_server/routers/service_connectors_endpoints.py +94 -14
- zenml/zen_server/routers/service_endpoints.py +18 -7
- zenml/zen_server/routers/stack_components_endpoints.py +66 -7
- zenml/zen_server/routers/stacks_endpoints.py +95 -6
- zenml/zen_server/routers/steps_endpoints.py +17 -11
- zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
- zenml/zen_server/routers/tags_endpoints.py +6 -17
- zenml/zen_server/routers/triggers_endpoints.py +5 -8
- zenml/zen_server/routers/users_endpoints.py +9 -12
- zenml/zen_server/template_execution/utils.py +8 -7
- zenml/zen_server/utils.py +21 -0
- zenml/zen_server/zen_server_api.py +7 -2
- zenml/zen_stores/base_zen_store.py +50 -69
- zenml/zen_stores/migrations/versions/12eff0206201_rename_workspace_to_project.py +768 -0
- zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
- zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
- zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
- zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
- zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
- zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
- zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
- zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
- zenml/zen_stores/migrations/versions/cbc6acd71f92_add_workspace_display_name.py +58 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
- zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
- zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
- zenml/zen_stores/rest_zen_store.py +223 -230
- zenml/zen_stores/schemas/__init__.py +2 -2
- zenml/zen_stores/schemas/action_schemas.py +15 -8
- zenml/zen_stores/schemas/api_key_schemas.py +8 -1
- zenml/zen_stores/schemas/artifact_schemas.py +35 -10
- zenml/zen_stores/schemas/code_repository_schemas.py +22 -17
- zenml/zen_stores/schemas/component_schemas.py +9 -14
- zenml/zen_stores/schemas/event_source_schemas.py +15 -8
- zenml/zen_stores/schemas/flavor_schemas.py +14 -20
- zenml/zen_stores/schemas/model_schemas.py +18 -17
- zenml/zen_stores/schemas/pipeline_build_schemas.py +7 -7
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +10 -8
- zenml/zen_stores/schemas/pipeline_run_schemas.py +9 -12
- zenml/zen_stores/schemas/pipeline_schemas.py +9 -9
- zenml/zen_stores/schemas/{workspace_schemas.py → project_schemas.py} +53 -65
- zenml/zen_stores/schemas/run_metadata_schemas.py +5 -5
- zenml/zen_stores/schemas/run_template_schemas.py +17 -13
- zenml/zen_stores/schemas/schedule_schema.py +16 -21
- zenml/zen_stores/schemas/secret_schemas.py +15 -25
- zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
- zenml/zen_stores/schemas/service_schemas.py +7 -8
- zenml/zen_stores/schemas/stack_schemas.py +12 -15
- zenml/zen_stores/schemas/step_run_schemas.py +14 -15
- zenml/zen_stores/schemas/tag_schemas.py +30 -2
- zenml/zen_stores/schemas/trigger_schemas.py +15 -8
- zenml/zen_stores/schemas/user_schemas.py +12 -2
- zenml/zen_stores/schemas/utils.py +16 -0
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
- zenml/zen_stores/sql_zen_store.py +2984 -2369
- zenml/zen_stores/template_utils.py +1 -1
- zenml/zen_stores/zen_store_interface.py +136 -126
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/METADATA +1 -1
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/RECORD +188 -173
- zenml/cli/workspace.py +0 -86
- zenml/models/v2/core/workspace.py +0 -131
- zenml/zen_server/routers/workspaces_endpoints.py +0 -1469
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/entry_points.txt +0 -0
@@ -66,7 +66,10 @@ from zenml.zen_server.auth import (
|
|
66
66
|
from zenml.zen_server.exceptions import error_response
|
67
67
|
from zenml.zen_server.rate_limit import rate_limit_requests
|
68
68
|
from zenml.zen_server.rbac.models import Action, ResourceType
|
69
|
-
from zenml.zen_server.rbac.utils import
|
69
|
+
from zenml.zen_server.rbac.utils import (
|
70
|
+
verify_permission,
|
71
|
+
verify_permission_for_model,
|
72
|
+
)
|
70
73
|
from zenml.zen_server.utils import (
|
71
74
|
get_ip_location,
|
72
75
|
handle_exceptions,
|
@@ -544,10 +547,6 @@ def api_token(
|
|
544
547
|
response=None,
|
545
548
|
).access_token
|
546
549
|
|
547
|
-
verify_permission(
|
548
|
-
resource_type=ResourceType.PIPELINE_RUN, action=Action.CREATE
|
549
|
-
)
|
550
|
-
|
551
550
|
schedule_id = schedule_id or token.schedule_id
|
552
551
|
pipeline_run_id = pipeline_run_id or token.pipeline_run_id
|
553
552
|
step_run_id = step_run_id or token.step_run_id
|
@@ -583,15 +582,18 @@ def api_token(
|
|
583
582
|
f"step run {token.step_run_id}."
|
584
583
|
)
|
585
584
|
|
585
|
+
project_id: Optional[UUID] = None
|
586
|
+
|
586
587
|
if schedule_id:
|
587
588
|
# The schedule must exist
|
588
589
|
try:
|
589
|
-
schedule = zen_store().get_schedule(schedule_id, hydrate=
|
590
|
+
schedule = zen_store().get_schedule(schedule_id, hydrate=True)
|
590
591
|
except KeyError:
|
591
592
|
raise ValueError(
|
592
593
|
f"Schedule {schedule_id} does not exist and API tokens cannot "
|
593
594
|
"be generated for non-existent schedules for security reasons."
|
594
595
|
)
|
596
|
+
project_id = schedule.project.id
|
595
597
|
|
596
598
|
if not schedule.active:
|
597
599
|
raise ValueError(
|
@@ -602,7 +604,7 @@ def api_token(
|
|
602
604
|
if pipeline_run_id:
|
603
605
|
# The pipeline run must exist and the run must not be concluded
|
604
606
|
try:
|
605
|
-
pipeline_run = zen_store().get_run(pipeline_run_id, hydrate=
|
607
|
+
pipeline_run = zen_store().get_run(pipeline_run_id, hydrate=True)
|
606
608
|
except KeyError:
|
607
609
|
raise ValueError(
|
608
610
|
f"Pipeline run {pipeline_run_id} does not exist and API tokens "
|
@@ -610,6 +612,10 @@ def api_token(
|
|
610
612
|
"security reasons."
|
611
613
|
)
|
612
614
|
|
615
|
+
verify_permission_for_model(model=pipeline_run, action=Action.READ)
|
616
|
+
|
617
|
+
project_id = pipeline_run.project.id
|
618
|
+
|
613
619
|
if pipeline_run.status.is_finished:
|
614
620
|
raise ValueError(
|
615
621
|
f"The execution of pipeline run {pipeline_run_id} has already "
|
@@ -627,6 +633,8 @@ def api_token(
|
|
627
633
|
"be generated for non-existent step runs for security reasons."
|
628
634
|
)
|
629
635
|
|
636
|
+
project_id = step_run.project.id
|
637
|
+
|
630
638
|
if step_run.status.is_finished:
|
631
639
|
raise ValueError(
|
632
640
|
f"The execution of step run {step_run_id} has already "
|
@@ -634,6 +642,13 @@ def api_token(
|
|
634
642
|
"for security reasons."
|
635
643
|
)
|
636
644
|
|
645
|
+
assert project_id is not None
|
646
|
+
verify_permission(
|
647
|
+
resource_type=ResourceType.PIPELINE_RUN,
|
648
|
+
action=Action.CREATE,
|
649
|
+
project_id=project_id,
|
650
|
+
)
|
651
|
+
|
637
652
|
return generate_access_token(
|
638
653
|
user_id=token.user_id,
|
639
654
|
# Keep the original API key and device token scopes
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for code repositories."""
|
15
15
|
|
16
|
+
from typing import Optional, Union
|
16
17
|
from uuid import UUID
|
17
18
|
|
18
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -20,6 +21,7 @@ from fastapi import APIRouter, Depends, Security
|
|
20
21
|
from zenml.constants import API, CODE_REPOSITORIES, VERSION_1
|
21
22
|
from zenml.models import (
|
22
23
|
CodeRepositoryFilter,
|
24
|
+
CodeRepositoryRequest,
|
23
25
|
CodeRepositoryResponse,
|
24
26
|
CodeRepositoryUpdate,
|
25
27
|
Page,
|
@@ -27,12 +29,14 @@ from zenml.models import (
|
|
27
29
|
from zenml.zen_server.auth import AuthContext, authorize
|
28
30
|
from zenml.zen_server.exceptions import error_response
|
29
31
|
from zenml.zen_server.rbac.endpoint_utils import (
|
32
|
+
verify_permissions_and_create_entity,
|
30
33
|
verify_permissions_and_delete_entity,
|
31
34
|
verify_permissions_and_get_entity,
|
32
35
|
verify_permissions_and_list_entities,
|
33
36
|
verify_permissions_and_update_entity,
|
34
37
|
)
|
35
38
|
from zenml.zen_server.rbac.models import ResourceType
|
39
|
+
from zenml.zen_server.routers.projects_endpoints import workspace_router
|
36
40
|
from zenml.zen_server.utils import (
|
37
41
|
handle_exceptions,
|
38
42
|
make_dependable,
|
@@ -46,16 +50,61 @@ router = APIRouter(
|
|
46
50
|
)
|
47
51
|
|
48
52
|
|
53
|
+
@router.post(
|
54
|
+
"",
|
55
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
56
|
+
)
|
57
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
58
|
+
# and can be removed after the migration
|
59
|
+
@workspace_router.post(
|
60
|
+
"/{project_name_or_id}" + CODE_REPOSITORIES,
|
61
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
62
|
+
deprecated=True,
|
63
|
+
tags=["code_repositories"],
|
64
|
+
)
|
65
|
+
@handle_exceptions
|
66
|
+
def create_code_repository(
|
67
|
+
code_repository: CodeRepositoryRequest,
|
68
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
69
|
+
_: AuthContext = Security(authorize),
|
70
|
+
) -> CodeRepositoryResponse:
|
71
|
+
"""Creates a code repository.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
code_repository: Code repository to create.
|
75
|
+
project_name_or_id: Optional name or ID of the project.
|
76
|
+
|
77
|
+
Returns:
|
78
|
+
The created code repository.
|
79
|
+
"""
|
80
|
+
if project_name_or_id:
|
81
|
+
project = zen_store().get_project(project_name_or_id)
|
82
|
+
code_repository.project = project.id
|
83
|
+
|
84
|
+
return verify_permissions_and_create_entity(
|
85
|
+
request_model=code_repository,
|
86
|
+
create_method=zen_store().create_code_repository,
|
87
|
+
)
|
88
|
+
|
89
|
+
|
49
90
|
@router.get(
|
50
91
|
"",
|
51
|
-
response_model=Page[CodeRepositoryResponse],
|
52
92
|
responses={401: error_response, 404: error_response, 422: error_response},
|
53
93
|
)
|
94
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
95
|
+
# and can be removed after the migration
|
96
|
+
@workspace_router.get(
|
97
|
+
"/{project_name_or_id}" + CODE_REPOSITORIES,
|
98
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
99
|
+
deprecated=True,
|
100
|
+
tags=["code_repositories"],
|
101
|
+
)
|
54
102
|
@handle_exceptions
|
55
103
|
def list_code_repositories(
|
56
104
|
filter_model: CodeRepositoryFilter = Depends(
|
57
105
|
make_dependable(CodeRepositoryFilter)
|
58
106
|
),
|
107
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
59
108
|
hydrate: bool = False,
|
60
109
|
_: AuthContext = Security(authorize),
|
61
110
|
) -> Page[CodeRepositoryResponse]:
|
@@ -64,12 +113,16 @@ def list_code_repositories(
|
|
64
113
|
Args:
|
65
114
|
filter_model: Filter model used for pagination, sorting,
|
66
115
|
filtering.
|
116
|
+
project_name_or_id: Optional name or ID of the project.
|
67
117
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
68
118
|
by including metadata fields in the response.
|
69
119
|
|
70
120
|
Returns:
|
71
121
|
Page of code repository objects.
|
72
122
|
"""
|
123
|
+
if project_name_or_id:
|
124
|
+
filter_model.project = project_name_or_id
|
125
|
+
|
73
126
|
return verify_permissions_and_list_entities(
|
74
127
|
filter_model=filter_model,
|
75
128
|
resource_type=ResourceType.CODE_REPOSITORY,
|
@@ -80,7 +133,6 @@ def list_code_repositories(
|
|
80
133
|
|
81
134
|
@router.get(
|
82
135
|
"/{code_repository_id}",
|
83
|
-
response_model=CodeRepositoryResponse,
|
84
136
|
responses={401: error_response, 404: error_response, 422: error_response},
|
85
137
|
)
|
86
138
|
@handle_exceptions
|
@@ -108,7 +160,6 @@ def get_code_repository(
|
|
108
160
|
|
109
161
|
@router.put(
|
110
162
|
"/{code_repository_id}",
|
111
|
-
response_model=CodeRepositoryResponse,
|
112
163
|
responses={401: error_response, 404: error_response, 422: error_response},
|
113
164
|
)
|
114
165
|
@handle_exceptions
|
@@ -54,7 +54,6 @@ router = APIRouter(
|
|
54
54
|
|
55
55
|
@router.get(
|
56
56
|
"",
|
57
|
-
response_model=Page[OAuthDeviceResponse],
|
58
57
|
responses={401: error_response, 404: error_response, 422: error_response},
|
59
58
|
)
|
60
59
|
@handle_exceptions
|
@@ -85,7 +84,6 @@ def list_authorized_devices(
|
|
85
84
|
|
86
85
|
@router.get(
|
87
86
|
"/{device_id}",
|
88
|
-
response_model=OAuthDeviceResponse,
|
89
87
|
responses={401: error_response, 404: error_response, 422: error_response},
|
90
88
|
)
|
91
89
|
@handle_exceptions
|
@@ -136,7 +134,6 @@ def get_authorization_device(
|
|
136
134
|
|
137
135
|
@router.put(
|
138
136
|
"/{device_id}",
|
139
|
-
response_model=OAuthDeviceResponse,
|
140
137
|
responses={401: error_response, 404: error_response, 422: error_response},
|
141
138
|
)
|
142
139
|
@handle_exceptions
|
@@ -173,7 +170,6 @@ def update_authorized_device(
|
|
173
170
|
|
174
171
|
@router.put(
|
175
172
|
"/{device_id}" + DEVICE_VERIFY,
|
176
|
-
response_model=OAuthDeviceResponse,
|
177
173
|
responses={401: error_response, 404: error_response, 422: error_response},
|
178
174
|
)
|
179
175
|
@handle_exceptions
|
@@ -57,7 +57,6 @@ event_source_router = APIRouter(
|
|
57
57
|
|
58
58
|
@event_source_router.get(
|
59
59
|
"",
|
60
|
-
response_model=Page[EventSourceResponse],
|
61
60
|
responses={401: error_response, 404: error_response, 422: error_response},
|
62
61
|
)
|
63
62
|
@handle_exceptions
|
@@ -132,7 +131,6 @@ def list_event_sources(
|
|
132
131
|
|
133
132
|
@event_source_router.get(
|
134
133
|
"/{event_source_id}",
|
135
|
-
response_model=EventSourceResponse,
|
136
134
|
responses={401: error_response, 404: error_response, 422: error_response},
|
137
135
|
)
|
138
136
|
@handle_exceptions
|
@@ -185,7 +183,6 @@ def get_event_source(
|
|
185
183
|
|
186
184
|
@event_source_router.post(
|
187
185
|
"",
|
188
|
-
response_model=EventSourceResponse,
|
189
186
|
responses={401: error_response, 409: error_response, 422: error_response},
|
190
187
|
)
|
191
188
|
@handle_exceptions
|
@@ -222,14 +219,12 @@ def create_event_source(
|
|
222
219
|
|
223
220
|
return verify_permissions_and_create_entity(
|
224
221
|
request_model=event_source,
|
225
|
-
resource_type=ResourceType.EVENT_SOURCE,
|
226
222
|
create_method=event_source_handler.create_event_source,
|
227
223
|
)
|
228
224
|
|
229
225
|
|
230
226
|
@event_source_router.put(
|
231
227
|
"/{event_source_id}",
|
232
|
-
response_model=EventSourceResponse,
|
233
228
|
responses={401: error_response, 404: error_response, 422: error_response},
|
234
229
|
)
|
235
230
|
@handle_exceptions
|
@@ -51,7 +51,6 @@ router = APIRouter(
|
|
51
51
|
|
52
52
|
@router.get(
|
53
53
|
"",
|
54
|
-
response_model=Page[FlavorResponse],
|
55
54
|
responses={401: error_response, 404: error_response, 422: error_response},
|
56
55
|
)
|
57
56
|
@handle_exceptions
|
@@ -81,7 +80,6 @@ def list_flavors(
|
|
81
80
|
|
82
81
|
@router.get(
|
83
82
|
"/{flavor_id}",
|
84
|
-
response_model=FlavorResponse,
|
85
83
|
responses={401: error_response, 404: error_response, 422: error_response},
|
86
84
|
)
|
87
85
|
@handle_exceptions
|
@@ -107,7 +105,6 @@ def get_flavor(
|
|
107
105
|
|
108
106
|
@router.post(
|
109
107
|
"",
|
110
|
-
response_model=FlavorResponse,
|
111
108
|
responses={401: error_response, 409: error_response, 422: error_response},
|
112
109
|
)
|
113
110
|
@handle_exceptions
|
@@ -125,14 +122,12 @@ def create_flavor(
|
|
125
122
|
"""
|
126
123
|
return verify_permissions_and_create_entity(
|
127
124
|
request_model=flavor,
|
128
|
-
resource_type=ResourceType.FLAVOR,
|
129
125
|
create_method=zen_store().create_flavor,
|
130
126
|
)
|
131
127
|
|
132
128
|
|
133
129
|
@router.put(
|
134
130
|
"/{flavor_id}",
|
135
|
-
response_model=FlavorResponse,
|
136
131
|
responses={401: error_response, 409: error_response, 422: error_response},
|
137
132
|
)
|
138
133
|
@handle_exceptions
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for models."""
|
15
15
|
|
16
|
-
from typing import Union
|
16
|
+
from typing import Optional, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -24,6 +24,7 @@ from zenml.constants import (
|
|
24
24
|
MODEL_VERSION_ARTIFACTS,
|
25
25
|
MODEL_VERSION_PIPELINE_RUNS,
|
26
26
|
MODEL_VERSIONS,
|
27
|
+
MODELS,
|
27
28
|
RUNS,
|
28
29
|
VERSION_1,
|
29
30
|
)
|
@@ -35,22 +36,31 @@ from zenml.models import (
|
|
35
36
|
ModelVersionPipelineRunFilter,
|
36
37
|
ModelVersionPipelineRunRequest,
|
37
38
|
ModelVersionPipelineRunResponse,
|
39
|
+
ModelVersionRequest,
|
38
40
|
ModelVersionResponse,
|
39
41
|
ModelVersionUpdate,
|
40
42
|
)
|
41
43
|
from zenml.models.v2.base.page import Page
|
42
44
|
from zenml.zen_server.auth import AuthContext, authorize
|
43
45
|
from zenml.zen_server.exceptions import error_response
|
44
|
-
from zenml.zen_server.rbac.
|
46
|
+
from zenml.zen_server.rbac.endpoint_utils import (
|
47
|
+
verify_permissions_and_create_entity,
|
48
|
+
verify_permissions_and_delete_entity,
|
49
|
+
)
|
50
|
+
from zenml.zen_server.rbac.models import Action
|
45
51
|
from zenml.zen_server.rbac.utils import (
|
46
52
|
dehydrate_page,
|
47
53
|
dehydrate_response_model,
|
48
|
-
get_allowed_resource_ids,
|
49
54
|
verify_permission_for_model,
|
50
55
|
)
|
56
|
+
from zenml.zen_server.routers.models_endpoints import (
|
57
|
+
router as model_router,
|
58
|
+
)
|
59
|
+
from zenml.zen_server.routers.projects_endpoints import workspace_router
|
51
60
|
from zenml.zen_server.utils import (
|
52
61
|
handle_exceptions,
|
53
62
|
make_dependable,
|
63
|
+
set_filter_project_scope,
|
54
64
|
zen_store,
|
55
65
|
)
|
56
66
|
|
@@ -66,9 +76,54 @@ router = APIRouter(
|
|
66
76
|
)
|
67
77
|
|
68
78
|
|
79
|
+
@router.post(
|
80
|
+
"",
|
81
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
82
|
+
)
|
83
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
84
|
+
# and can be removed after the migration
|
85
|
+
@workspace_router.post(
|
86
|
+
"/{project_name_or_id}" + MODELS + "/{model_id}" + MODEL_VERSIONS,
|
87
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
88
|
+
deprecated=True,
|
89
|
+
tags=["model_versions"],
|
90
|
+
)
|
91
|
+
@handle_exceptions
|
92
|
+
def create_model_version(
|
93
|
+
model_version: ModelVersionRequest,
|
94
|
+
model_id: Optional[UUID] = None,
|
95
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
96
|
+
_: AuthContext = Security(authorize),
|
97
|
+
) -> ModelVersionResponse:
|
98
|
+
"""Creates a model version.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
model_version: Model version to create.
|
102
|
+
model_id: Optional ID of the model.
|
103
|
+
project_name_or_id: Optional name or ID of the project.
|
104
|
+
|
105
|
+
Returns:
|
106
|
+
The created model version.
|
107
|
+
"""
|
108
|
+
if project_name_or_id:
|
109
|
+
project = zen_store().get_project(project_name_or_id)
|
110
|
+
model_version.project = project.id
|
111
|
+
|
112
|
+
if model_id:
|
113
|
+
model_version.model = model_id
|
114
|
+
|
115
|
+
return verify_permissions_and_create_entity(
|
116
|
+
request_model=model_version,
|
117
|
+
create_method=zen_store().create_model_version,
|
118
|
+
)
|
119
|
+
|
120
|
+
|
121
|
+
@model_router.get(
|
122
|
+
"/{model_name_or_id}" + MODEL_VERSIONS,
|
123
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
124
|
+
)
|
69
125
|
@router.get(
|
70
126
|
"",
|
71
|
-
response_model=Page[ModelVersionResponse],
|
72
127
|
responses={401: error_response, 404: error_response, 422: error_response},
|
73
128
|
)
|
74
129
|
@handle_exceptions
|
@@ -76,6 +131,7 @@ def list_model_versions(
|
|
76
131
|
model_version_filter_model: ModelVersionFilter = Depends(
|
77
132
|
make_dependable(ModelVersionFilter)
|
78
133
|
),
|
134
|
+
model_name_or_id: Optional[Union[str, UUID]] = None,
|
79
135
|
hydrate: bool = False,
|
80
136
|
auth_context: AuthContext = Security(authorize),
|
81
137
|
) -> Page[ModelVersionResponse]:
|
@@ -84,19 +140,38 @@ def list_model_versions(
|
|
84
140
|
Args:
|
85
141
|
model_version_filter_model: Filter model used for pagination, sorting,
|
86
142
|
filtering.
|
143
|
+
model_name_or_id: Optional name or ID of the model.
|
87
144
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
88
145
|
by including metadata fields in the response.
|
89
146
|
auth_context: The authentication context.
|
90
147
|
|
91
148
|
Returns:
|
92
149
|
The model versions according to query filters.
|
150
|
+
|
151
|
+
Raises:
|
152
|
+
ValueError: If the model is missing from the filter.
|
93
153
|
"""
|
94
|
-
|
95
|
-
|
154
|
+
if model_name_or_id:
|
155
|
+
model_version_filter_model.model = model_name_or_id
|
156
|
+
|
157
|
+
if not model_version_filter_model.model:
|
158
|
+
raise ValueError("Model missing from the filter")
|
159
|
+
|
160
|
+
# A project scoped request must always be scoped to a specific
|
161
|
+
# project. This is required for the RBAC check to work.
|
162
|
+
set_filter_project_scope(model_version_filter_model)
|
163
|
+
assert isinstance(model_version_filter_model.project, UUID)
|
164
|
+
|
165
|
+
model = zen_store().get_model_by_name_or_id(
|
166
|
+
model_version_filter_model.model,
|
167
|
+
project=model_version_filter_model.project,
|
96
168
|
)
|
169
|
+
|
170
|
+
# Check read permissions on the model
|
171
|
+
verify_permission_for_model(model, action=Action.READ)
|
172
|
+
|
97
173
|
model_version_filter_model.configure_rbac(
|
98
|
-
authenticated_user_id=auth_context.user.id
|
99
|
-
model_id=allowed_model_ids,
|
174
|
+
authenticated_user_id=auth_context.user.id
|
100
175
|
)
|
101
176
|
|
102
177
|
model_versions = zen_store().list_model_versions(
|
@@ -108,7 +183,6 @@ def list_model_versions(
|
|
108
183
|
|
109
184
|
@router.get(
|
110
185
|
"/{model_version_id}",
|
111
|
-
response_model=ModelVersionResponse,
|
112
186
|
responses={401: error_response, 404: error_response, 422: error_response},
|
113
187
|
)
|
114
188
|
@handle_exceptions
|
@@ -137,7 +211,6 @@ def get_model_version(
|
|
137
211
|
|
138
212
|
@router.put(
|
139
213
|
"/{model_version_id}",
|
140
|
-
response_model=ModelVersionResponse,
|
141
214
|
responses={401: error_response, 404: error_response, 422: error_response},
|
142
215
|
)
|
143
216
|
@handle_exceptions
|
@@ -184,9 +257,11 @@ def delete_model_version(
|
|
184
257
|
Args:
|
185
258
|
model_version_id: The name or ID of the model version to delete.
|
186
259
|
"""
|
187
|
-
|
188
|
-
|
189
|
-
|
260
|
+
verify_permissions_and_delete_entity(
|
261
|
+
id=model_version_id,
|
262
|
+
get_method=zen_store().get_model_version,
|
263
|
+
delete_method=zen_store().delete_model_version,
|
264
|
+
)
|
190
265
|
|
191
266
|
|
192
267
|
##########################
|
@@ -220,17 +295,18 @@ def create_model_version_artifact_link(
|
|
220
295
|
model_version = zen_store().get_model_version(
|
221
296
|
model_version_artifact_link.model_version
|
222
297
|
)
|
223
|
-
verify_permission_for_model(model_version, action=Action.UPDATE)
|
224
298
|
|
225
|
-
|
226
|
-
model_version_artifact_link
|
299
|
+
return verify_permissions_and_create_entity(
|
300
|
+
request_model=model_version_artifact_link,
|
301
|
+
create_method=zen_store().create_model_version_artifact_link,
|
302
|
+
# Check for UPDATE permissions on the model version instead of the
|
303
|
+
# model version artifact link
|
304
|
+
surrogate_models=[model_version],
|
227
305
|
)
|
228
|
-
return mv
|
229
306
|
|
230
307
|
|
231
308
|
@model_version_artifacts_router.get(
|
232
309
|
"",
|
233
|
-
response_model=Page[ModelVersionArtifactResponse],
|
234
310
|
responses={401: error_response, 404: error_response, 422: error_response},
|
235
311
|
)
|
236
312
|
@handle_exceptions
|
@@ -342,17 +418,18 @@ def create_model_version_pipeline_run_link(
|
|
342
418
|
model_version = zen_store().get_model_version(
|
343
419
|
model_version_pipeline_run_link.model_version, hydrate=False
|
344
420
|
)
|
345
|
-
verify_permission_for_model(model_version, action=Action.UPDATE)
|
346
421
|
|
347
|
-
|
348
|
-
model_version_pipeline_run_link
|
422
|
+
return verify_permissions_and_create_entity(
|
423
|
+
request_model=model_version_pipeline_run_link,
|
424
|
+
create_method=zen_store().create_model_version_pipeline_run_link,
|
425
|
+
# Check for UPDATE permissions on the model version instead of the
|
426
|
+
# model version pipeline run link
|
427
|
+
surrogate_models=[model_version],
|
349
428
|
)
|
350
|
-
return mv
|
351
429
|
|
352
430
|
|
353
431
|
@model_version_pipeline_runs_router.get(
|
354
432
|
"",
|
355
|
-
response_model=Page[ModelVersionPipelineRunResponse],
|
356
433
|
responses={401: error_response, 404: error_response, 422: error_response},
|
357
434
|
)
|
358
435
|
@handle_exceptions
|