zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250313__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/artifacts/utils.py +0 -2
- zenml/cli/login.py +6 -0
- zenml/cli/model.py +7 -15
- zenml/cli/secret.py +47 -44
- zenml/cli/service_connectors.py +0 -1
- zenml/cli/stack.py +0 -1
- zenml/cli/tag.py +3 -5
- zenml/cli/utils.py +25 -23
- zenml/cli/workspace.py +79 -5
- zenml/client.py +615 -348
- zenml/config/global_config.py +16 -3
- 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 +1 -3
- 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/github/plugins/event_sources/github_webhook_event_source.py +1 -4
- zenml/integrations/mlflow/steps/mlflow_registry.py +1 -1
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +3 -3
- zenml/model/model.py +8 -8
- zenml/models/__init__.py +18 -1
- zenml/models/v2/base/base.py +0 -5
- zenml/models/v2/base/filter.py +1 -1
- zenml/models/v2/base/scoped.py +104 -121
- zenml/models/v2/core/api_key.py +1 -1
- zenml/models/v2/core/artifact.py +31 -18
- zenml/models/v2/core/artifact_version.py +42 -25
- zenml/models/v2/core/component.py +22 -33
- zenml/models/v2/core/device.py +3 -2
- zenml/models/v2/core/event_source.py +2 -2
- zenml/models/v2/core/flavor.py +19 -47
- zenml/models/v2/core/logs.py +1 -2
- zenml/models/v2/core/model.py +7 -4
- zenml/models/v2/core/model_version.py +36 -27
- zenml/models/v2/core/pipeline.py +1 -1
- zenml/models/v2/core/pipeline_run.py +5 -13
- zenml/models/v2/core/run_template.py +1 -2
- zenml/models/v2/core/schedule.py +0 -9
- zenml/models/v2/core/secret.py +93 -127
- zenml/models/v2/core/server_settings.py +2 -2
- zenml/models/v2/core/service.py +43 -12
- zenml/models/v2/core/service_connector.py +14 -16
- zenml/models/v2/core/stack.py +24 -26
- zenml/models/v2/core/step_run.py +3 -15
- zenml/models/v2/core/tag.py +41 -15
- zenml/models/v2/core/user.py +19 -2
- zenml/models/v2/misc/statistics.py +45 -0
- zenml/models/v2/misc/tag.py +27 -0
- zenml/orchestrators/cache_utils.py +1 -1
- zenml/orchestrators/input_utils.py +1 -0
- zenml/orchestrators/step_launcher.py +0 -1
- zenml/orchestrators/step_run_utils.py +0 -2
- zenml/orchestrators/step_runner.py +10 -1
- zenml/pipelines/build_utils.py +0 -2
- zenml/pipelines/pipeline_decorator.py +3 -2
- zenml/pipelines/pipeline_definition.py +4 -5
- zenml/pipelines/run_utils.py +3 -3
- zenml/service_connectors/service_connector.py +0 -7
- zenml/service_connectors/service_connector_utils.py +0 -1
- zenml/stack/authentication_mixin.py +1 -1
- zenml/stack/flavor.py +3 -14
- zenml/stack/stack_component.py +1 -5
- 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 +156 -29
- zenml/zen_server/rbac/zenml_cloud_rbac.py +43 -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 +56 -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 +102 -23
- zenml/zen_server/routers/models_endpoints.py +51 -68
- zenml/zen_server/routers/pipeline_builds_endpoints.py +58 -4
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +58 -4
- zenml/zen_server/routers/pipelines_endpoints.py +73 -4
- zenml/zen_server/routers/plugin_endpoints.py +0 -1
- zenml/zen_server/routers/run_metadata_endpoints.py +99 -0
- zenml/zen_server/routers/run_templates_endpoints.py +66 -3
- zenml/zen_server/routers/runs_endpoints.py +60 -8
- zenml/zen_server/routers/schedule_endpoints.py +69 -6
- zenml/zen_server/routers/secrets_endpoints.py +40 -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 +96 -14
- zenml/zen_server/routers/service_endpoints.py +20 -7
- zenml/zen_server/routers/stack_components_endpoints.py +68 -7
- zenml/zen_server/routers/stacks_endpoints.py +98 -7
- 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 +47 -12
- zenml/zen_server/routers/workspaces_endpoints.py +56 -1285
- zenml/zen_server/template_execution/utils.py +5 -4
- zenml/zen_server/utils.py +21 -0
- zenml/zen_server/zen_server_api.py +4 -0
- zenml/zen_stores/base_zen_store.py +29 -44
- 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/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 +172 -171
- zenml/zen_stores/schemas/action_schemas.py +8 -1
- zenml/zen_stores/schemas/api_key_schemas.py +8 -1
- zenml/zen_stores/schemas/artifact_schemas.py +28 -1
- zenml/zen_stores/schemas/code_repository_schemas.py +8 -1
- zenml/zen_stores/schemas/component_schemas.py +9 -14
- zenml/zen_stores/schemas/event_source_schemas.py +8 -1
- zenml/zen_stores/schemas/flavor_schemas.py +14 -20
- zenml/zen_stores/schemas/model_schemas.py +3 -0
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -1
- zenml/zen_stores/schemas/pipeline_run_schemas.py +0 -3
- zenml/zen_stores/schemas/run_template_schemas.py +8 -4
- zenml/zen_stores/schemas/schedule_schema.py +9 -14
- 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 +0 -1
- zenml/zen_stores/schemas/stack_schemas.py +12 -15
- zenml/zen_stores/schemas/step_run_schemas.py +7 -8
- zenml/zen_stores/schemas/tag_schemas.py +30 -2
- zenml/zen_stores/schemas/trigger_schemas.py +8 -1
- zenml/zen_stores/schemas/user_schemas.py +24 -2
- zenml/zen_stores/schemas/utils.py +16 -0
- zenml/zen_stores/schemas/workspace_schemas.py +7 -25
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
- zenml/zen_stores/sql_zen_store.py +2905 -2280
- zenml/zen_stores/template_utils.py +1 -1
- zenml/zen_stores/zen_store_interface.py +82 -58
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +160 -147
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for run templates."""
|
15
15
|
|
16
|
-
from typing import Optional
|
16
|
+
from typing import Optional, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, BackgroundTasks, Depends, Security
|
@@ -26,12 +26,14 @@ from zenml.models import (
|
|
26
26
|
Page,
|
27
27
|
PipelineRunResponse,
|
28
28
|
RunTemplateFilter,
|
29
|
+
RunTemplateRequest,
|
29
30
|
RunTemplateResponse,
|
30
31
|
RunTemplateUpdate,
|
31
32
|
)
|
32
33
|
from zenml.zen_server.auth import AuthContext, authorize
|
33
34
|
from zenml.zen_server.exceptions import error_response
|
34
35
|
from zenml.zen_server.rbac.endpoint_utils import (
|
36
|
+
verify_permissions_and_create_entity,
|
35
37
|
verify_permissions_and_delete_entity,
|
36
38
|
verify_permissions_and_get_entity,
|
37
39
|
verify_permissions_and_list_entities,
|
@@ -39,6 +41,9 @@ from zenml.zen_server.rbac.endpoint_utils import (
|
|
39
41
|
)
|
40
42
|
from zenml.zen_server.rbac.models import Action, ResourceType
|
41
43
|
from zenml.zen_server.rbac.utils import verify_permission
|
44
|
+
from zenml.zen_server.routers.workspaces_endpoints import (
|
45
|
+
router as workspace_router,
|
46
|
+
)
|
42
47
|
from zenml.zen_server.utils import (
|
43
48
|
handle_exceptions,
|
44
49
|
make_dependable,
|
@@ -53,15 +58,61 @@ router = APIRouter(
|
|
53
58
|
)
|
54
59
|
|
55
60
|
|
61
|
+
@router.post(
|
62
|
+
"",
|
63
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
64
|
+
)
|
65
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
66
|
+
# and can be removed after the migration
|
67
|
+
@workspace_router.post(
|
68
|
+
"/{workspace_name_or_id}" + RUN_TEMPLATES,
|
69
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
70
|
+
deprecated=True,
|
71
|
+
tags=["run_templates"],
|
72
|
+
)
|
73
|
+
@handle_exceptions
|
74
|
+
def create_run_template(
|
75
|
+
run_template: RunTemplateRequest,
|
76
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
77
|
+
_: AuthContext = Security(authorize),
|
78
|
+
) -> RunTemplateResponse:
|
79
|
+
"""Create a run template.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
run_template: Run template to create.
|
83
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
84
|
+
|
85
|
+
Returns:
|
86
|
+
The created run template.
|
87
|
+
"""
|
88
|
+
if workspace_name_or_id:
|
89
|
+
workspace = zen_store().get_workspace(workspace_name_or_id)
|
90
|
+
run_template.workspace = workspace.id
|
91
|
+
|
92
|
+
return verify_permissions_and_create_entity(
|
93
|
+
request_model=run_template,
|
94
|
+
create_method=zen_store().create_run_template,
|
95
|
+
)
|
96
|
+
|
97
|
+
|
56
98
|
@router.get(
|
57
99
|
"",
|
58
100
|
responses={401: error_response, 404: error_response, 422: error_response},
|
59
101
|
)
|
102
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
103
|
+
# and can be removed after the migration
|
104
|
+
@workspace_router.get(
|
105
|
+
"/{workspace_name_or_id}" + RUN_TEMPLATES,
|
106
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
107
|
+
deprecated=True,
|
108
|
+
tags=["run_templates"],
|
109
|
+
)
|
60
110
|
@handle_exceptions
|
61
111
|
def list_run_templates(
|
62
112
|
filter_model: RunTemplateFilter = Depends(
|
63
113
|
make_dependable(RunTemplateFilter)
|
64
114
|
),
|
115
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
65
116
|
hydrate: bool = False,
|
66
117
|
_: AuthContext = Security(authorize),
|
67
118
|
) -> Page[RunTemplateResponse]:
|
@@ -70,12 +121,16 @@ def list_run_templates(
|
|
70
121
|
Args:
|
71
122
|
filter_model: Filter model used for pagination, sorting,
|
72
123
|
filtering.
|
124
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
73
125
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
74
126
|
by including metadata fields in the response.
|
75
127
|
|
76
128
|
Returns:
|
77
129
|
Page of run templates.
|
78
130
|
"""
|
131
|
+
if workspace_name_or_id:
|
132
|
+
filter_model.workspace = workspace_name_or_id
|
133
|
+
|
79
134
|
return verify_permissions_and_list_entities(
|
80
135
|
filter_model=filter_model,
|
81
136
|
resource_type=ResourceType.RUN_TEMPLATE,
|
@@ -189,19 +244,27 @@ if server_config().workload_manager_enabled:
|
|
189
244
|
"""
|
190
245
|
from zenml.zen_server.template_execution.utils import run_template
|
191
246
|
|
192
|
-
with track_handler(
|
247
|
+
with track_handler(
|
248
|
+
event=AnalyticsEvent.EXECUTED_RUN_TEMPLATE,
|
249
|
+
) as analytics_handler:
|
193
250
|
template = verify_permissions_and_get_entity(
|
194
251
|
id=template_id,
|
195
252
|
get_method=zen_store().get_run_template,
|
196
253
|
hydrate=True,
|
197
254
|
)
|
255
|
+
analytics_handler.metadata = {
|
256
|
+
"workspace_id": template.workspace.id,
|
257
|
+
}
|
198
258
|
|
199
259
|
verify_permission(
|
200
260
|
resource_type=ResourceType.PIPELINE_DEPLOYMENT,
|
201
261
|
action=Action.CREATE,
|
262
|
+
workspace_id=template.workspace.id,
|
202
263
|
)
|
203
264
|
verify_permission(
|
204
|
-
resource_type=ResourceType.PIPELINE_RUN,
|
265
|
+
resource_type=ResourceType.PIPELINE_RUN,
|
266
|
+
action=Action.CREATE,
|
267
|
+
workspace_id=template.workspace.id,
|
205
268
|
)
|
206
269
|
|
207
270
|
return run_template(
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for pipeline runs."""
|
15
15
|
|
16
|
-
from typing import Any, Dict
|
16
|
+
from typing import Any, Dict, Optional, Tuple, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -32,6 +32,7 @@ from zenml.logger import get_logger
|
|
32
32
|
from zenml.models import (
|
33
33
|
Page,
|
34
34
|
PipelineRunFilter,
|
35
|
+
PipelineRunRequest,
|
35
36
|
PipelineRunResponse,
|
36
37
|
PipelineRunUpdate,
|
37
38
|
StepRunFilter,
|
@@ -42,11 +43,17 @@ from zenml.zen_server.exceptions import error_response
|
|
42
43
|
from zenml.zen_server.rbac.endpoint_utils import (
|
43
44
|
verify_permissions_and_delete_entity,
|
44
45
|
verify_permissions_and_get_entity,
|
46
|
+
verify_permissions_and_get_or_create_entity,
|
45
47
|
verify_permissions_and_list_entities,
|
46
48
|
verify_permissions_and_update_entity,
|
47
49
|
)
|
48
50
|
from zenml.zen_server.rbac.models import Action, ResourceType
|
49
|
-
from zenml.zen_server.rbac.utils import
|
51
|
+
from zenml.zen_server.rbac.utils import (
|
52
|
+
verify_permission_for_model,
|
53
|
+
)
|
54
|
+
from zenml.zen_server.routers.workspaces_endpoints import (
|
55
|
+
router as workspace_router,
|
56
|
+
)
|
50
57
|
from zenml.zen_server.utils import (
|
51
58
|
handle_exceptions,
|
52
59
|
make_dependable,
|
@@ -63,16 +70,62 @@ router = APIRouter(
|
|
63
70
|
logger = get_logger(__name__)
|
64
71
|
|
65
72
|
|
73
|
+
@router.post(
|
74
|
+
"",
|
75
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
76
|
+
)
|
77
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
78
|
+
# and can be removed after the migration
|
79
|
+
@workspace_router.post(
|
80
|
+
"/{workspace_name_or_id}" + RUNS,
|
81
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
82
|
+
deprecated=True,
|
83
|
+
tags=["runs"],
|
84
|
+
)
|
85
|
+
@handle_exceptions
|
86
|
+
def get_or_create_pipeline_run(
|
87
|
+
pipeline_run: PipelineRunRequest,
|
88
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
89
|
+
_: AuthContext = Security(authorize),
|
90
|
+
) -> Tuple[PipelineRunResponse, bool]:
|
91
|
+
"""Get or create a pipeline run.
|
92
|
+
|
93
|
+
Args:
|
94
|
+
pipeline_run: Pipeline run to create.
|
95
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
The pipeline run and a boolean indicating whether the run was created
|
99
|
+
or not.
|
100
|
+
"""
|
101
|
+
if workspace_name_or_id:
|
102
|
+
workspace = zen_store().get_workspace(workspace_name_or_id)
|
103
|
+
pipeline_run.workspace = workspace.id
|
104
|
+
|
105
|
+
return verify_permissions_and_get_or_create_entity(
|
106
|
+
request_model=pipeline_run,
|
107
|
+
get_or_create_method=zen_store().get_or_create_run,
|
108
|
+
)
|
109
|
+
|
110
|
+
|
66
111
|
@router.get(
|
67
112
|
"",
|
68
|
-
response_model=Page[PipelineRunResponse],
|
69
113
|
responses={401: error_response, 404: error_response, 422: error_response},
|
70
114
|
)
|
115
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
116
|
+
# and can be removed after the migration
|
117
|
+
@workspace_router.get(
|
118
|
+
"/{workspace_name_or_id}" + RUNS,
|
119
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
120
|
+
deprecated=True,
|
121
|
+
tags=["runs"],
|
122
|
+
)
|
71
123
|
@handle_exceptions
|
72
124
|
def list_runs(
|
73
125
|
runs_filter_model: PipelineRunFilter = Depends(
|
74
126
|
make_dependable(PipelineRunFilter)
|
75
127
|
),
|
128
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
76
129
|
hydrate: bool = False,
|
77
130
|
_: AuthContext = Security(authorize),
|
78
131
|
) -> Page[PipelineRunResponse]:
|
@@ -80,12 +133,16 @@ def list_runs(
|
|
80
133
|
|
81
134
|
Args:
|
82
135
|
runs_filter_model: Filter model used for pagination, sorting, filtering.
|
136
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
83
137
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
84
138
|
by including metadata fields in the response.
|
85
139
|
|
86
140
|
Returns:
|
87
141
|
The pipeline runs according to query filters.
|
88
142
|
"""
|
143
|
+
if workspace_name_or_id:
|
144
|
+
runs_filter_model.workspace = workspace_name_or_id
|
145
|
+
|
89
146
|
return verify_permissions_and_list_entities(
|
90
147
|
filter_model=runs_filter_model,
|
91
148
|
resource_type=ResourceType.PIPELINE_RUN,
|
@@ -96,7 +153,6 @@ def list_runs(
|
|
96
153
|
|
97
154
|
@router.get(
|
98
155
|
"/{run_id}",
|
99
|
-
response_model=PipelineRunResponse,
|
100
156
|
responses={401: error_response, 404: error_response, 422: error_response},
|
101
157
|
)
|
102
158
|
@handle_exceptions
|
@@ -157,7 +213,6 @@ def get_run(
|
|
157
213
|
|
158
214
|
@router.put(
|
159
215
|
"/{run_id}",
|
160
|
-
response_model=PipelineRunResponse,
|
161
216
|
responses={401: error_response, 404: error_response, 422: error_response},
|
162
217
|
)
|
163
218
|
@handle_exceptions
|
@@ -206,7 +261,6 @@ def delete_run(
|
|
206
261
|
|
207
262
|
@router.get(
|
208
263
|
"/{run_id}" + STEPS,
|
209
|
-
response_model=Page[StepRunResponse],
|
210
264
|
responses={401: error_response, 404: error_response, 422: error_response},
|
211
265
|
)
|
212
266
|
@handle_exceptions
|
@@ -236,7 +290,6 @@ def get_run_steps(
|
|
236
290
|
|
237
291
|
@router.get(
|
238
292
|
"/{run_id}" + PIPELINE_CONFIGURATION,
|
239
|
-
response_model=Dict[str, Any],
|
240
293
|
responses={401: error_response, 404: error_response, 422: error_response},
|
241
294
|
)
|
242
295
|
@handle_exceptions
|
@@ -260,7 +313,6 @@ def get_pipeline_configuration(
|
|
260
313
|
|
261
314
|
@router.get(
|
262
315
|
"/{run_id}" + STATUS,
|
263
|
-
response_model=ExecutionStatus,
|
264
316
|
responses={401: error_response, 404: error_response, 422: error_response},
|
265
317
|
)
|
266
318
|
@handle_exceptions
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for pipeline run schedules."""
|
15
15
|
|
16
|
+
from typing import Optional, Union
|
16
17
|
from uuid import UUID
|
17
18
|
|
18
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -21,11 +22,18 @@ from zenml.constants import API, SCHEDULES, VERSION_1
|
|
21
22
|
from zenml.models import (
|
22
23
|
Page,
|
23
24
|
ScheduleFilter,
|
25
|
+
ScheduleRequest,
|
24
26
|
ScheduleResponse,
|
25
27
|
ScheduleUpdate,
|
26
28
|
)
|
27
29
|
from zenml.zen_server.auth import AuthContext, authorize
|
28
30
|
from zenml.zen_server.exceptions import error_response
|
31
|
+
from zenml.zen_server.rbac.endpoint_utils import (
|
32
|
+
verify_permissions_and_create_entity,
|
33
|
+
)
|
34
|
+
from zenml.zen_server.routers.workspaces_endpoints import (
|
35
|
+
router as workspace_router,
|
36
|
+
)
|
29
37
|
from zenml.zen_server.utils import (
|
30
38
|
handle_exceptions,
|
31
39
|
make_dependable,
|
@@ -39,16 +47,64 @@ router = APIRouter(
|
|
39
47
|
)
|
40
48
|
|
41
49
|
|
50
|
+
@router.post(
|
51
|
+
"",
|
52
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
53
|
+
)
|
54
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
55
|
+
# and can be removed after the migration
|
56
|
+
@workspace_router.post(
|
57
|
+
"/{workspace_name_or_id}" + SCHEDULES,
|
58
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
59
|
+
deprecated=True,
|
60
|
+
tags=["schedules"],
|
61
|
+
)
|
62
|
+
@handle_exceptions
|
63
|
+
def create_schedule(
|
64
|
+
schedule: ScheduleRequest,
|
65
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
66
|
+
auth_context: AuthContext = Security(authorize),
|
67
|
+
) -> ScheduleResponse:
|
68
|
+
"""Creates a schedule.
|
69
|
+
|
70
|
+
Args:
|
71
|
+
schedule: Schedule to create.
|
72
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
73
|
+
auth_context: Authentication context.
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
The created schedule.
|
77
|
+
"""
|
78
|
+
if workspace_name_or_id:
|
79
|
+
workspace = zen_store().get_workspace(workspace_name_or_id)
|
80
|
+
schedule.workspace = workspace.id
|
81
|
+
|
82
|
+
# NOTE: no RBAC is enforced currently for schedules, but we're
|
83
|
+
# keeping the RBAC checks here for consistency
|
84
|
+
return verify_permissions_and_create_entity(
|
85
|
+
request_model=schedule,
|
86
|
+
create_method=zen_store().create_schedule,
|
87
|
+
)
|
88
|
+
|
89
|
+
|
42
90
|
@router.get(
|
43
91
|
"",
|
44
|
-
response_model=Page[ScheduleResponse],
|
45
92
|
responses={401: error_response, 404: error_response, 422: error_response},
|
46
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
|
+
"/{workspace_name_or_id}" + SCHEDULES,
|
98
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
99
|
+
deprecated=True,
|
100
|
+
tags=["schedules"],
|
101
|
+
)
|
47
102
|
@handle_exceptions
|
48
103
|
def list_schedules(
|
49
104
|
schedule_filter_model: ScheduleFilter = Depends(
|
50
105
|
make_dependable(ScheduleFilter)
|
51
106
|
),
|
107
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
52
108
|
hydrate: bool = False,
|
53
109
|
_: AuthContext = Security(authorize),
|
54
110
|
) -> Page[ScheduleResponse]:
|
@@ -57,20 +113,24 @@ def list_schedules(
|
|
57
113
|
Args:
|
58
114
|
schedule_filter_model: Filter model used for pagination, sorting,
|
59
115
|
filtering
|
116
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
60
117
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
61
118
|
by including metadata fields in the response.
|
62
119
|
|
63
120
|
Returns:
|
64
121
|
List of schedule objects.
|
65
122
|
"""
|
123
|
+
if workspace_name_or_id:
|
124
|
+
schedule_filter_model.workspace = workspace_name_or_id
|
125
|
+
|
66
126
|
return zen_store().list_schedules(
|
67
|
-
schedule_filter_model=schedule_filter_model,
|
127
|
+
schedule_filter_model=schedule_filter_model,
|
128
|
+
hydrate=hydrate,
|
68
129
|
)
|
69
130
|
|
70
131
|
|
71
132
|
@router.get(
|
72
133
|
"/{schedule_id}",
|
73
|
-
response_model=ScheduleResponse,
|
74
134
|
responses={401: error_response, 404: error_response, 422: error_response},
|
75
135
|
)
|
76
136
|
@handle_exceptions
|
@@ -89,12 +149,14 @@ def get_schedule(
|
|
89
149
|
Returns:
|
90
150
|
A specific schedule object.
|
91
151
|
"""
|
92
|
-
return zen_store().get_schedule(
|
152
|
+
return zen_store().get_schedule(
|
153
|
+
schedule_id=schedule_id,
|
154
|
+
hydrate=hydrate,
|
155
|
+
)
|
93
156
|
|
94
157
|
|
95
158
|
@router.put(
|
96
159
|
"/{schedule_id}",
|
97
|
-
response_model=ScheduleResponse,
|
98
160
|
responses={401: error_response, 404: error_response, 422: error_response},
|
99
161
|
)
|
100
162
|
@handle_exceptions
|
@@ -113,7 +175,8 @@ def update_schedule(
|
|
113
175
|
The updated schedule object.
|
114
176
|
"""
|
115
177
|
return zen_store().update_schedule(
|
116
|
-
schedule_id=schedule_id,
|
178
|
+
schedule_id=schedule_id,
|
179
|
+
schedule_update=schedule_update,
|
117
180
|
)
|
118
181
|
|
119
182
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for pipeline run secrets."""
|
15
15
|
|
16
|
-
from typing import Optional
|
16
|
+
from typing import Optional, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -29,12 +29,14 @@ from zenml.constants import (
|
|
29
29
|
from zenml.models import (
|
30
30
|
Page,
|
31
31
|
SecretFilter,
|
32
|
+
SecretRequest,
|
32
33
|
SecretResponse,
|
33
34
|
SecretUpdate,
|
34
35
|
)
|
35
36
|
from zenml.zen_server.auth import AuthContext, authorize
|
36
37
|
from zenml.zen_server.exceptions import error_response
|
37
38
|
from zenml.zen_server.rbac.endpoint_utils import (
|
39
|
+
verify_permissions_and_create_entity,
|
38
40
|
verify_permissions_and_delete_entity,
|
39
41
|
verify_permissions_and_get_entity,
|
40
42
|
verify_permissions_and_list_entities,
|
@@ -47,6 +49,9 @@ from zenml.zen_server.rbac.utils import (
|
|
47
49
|
is_owned_by_authenticated_user,
|
48
50
|
verify_permission,
|
49
51
|
)
|
52
|
+
from zenml.zen_server.routers.workspaces_endpoints import (
|
53
|
+
router as workspace_router,
|
54
|
+
)
|
50
55
|
from zenml.zen_server.utils import (
|
51
56
|
handle_exceptions,
|
52
57
|
make_dependable,
|
@@ -66,9 +71,41 @@ op_router = APIRouter(
|
|
66
71
|
)
|
67
72
|
|
68
73
|
|
74
|
+
@router.post(
|
75
|
+
"",
|
76
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
77
|
+
)
|
78
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
79
|
+
# and can be removed after the migration
|
80
|
+
@workspace_router.post(
|
81
|
+
"/{workspace_name_or_id}" + SECRETS,
|
82
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
83
|
+
deprecated=True,
|
84
|
+
tags=["secrets"],
|
85
|
+
)
|
86
|
+
@handle_exceptions
|
87
|
+
def create_secret(
|
88
|
+
secret: SecretRequest,
|
89
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
90
|
+
_: AuthContext = Security(authorize),
|
91
|
+
) -> SecretResponse:
|
92
|
+
"""Creates a secret.
|
93
|
+
|
94
|
+
Args:
|
95
|
+
secret: Secret to create.
|
96
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
The created secret.
|
100
|
+
"""
|
101
|
+
return verify_permissions_and_create_entity(
|
102
|
+
request_model=secret,
|
103
|
+
create_method=zen_store().create_secret,
|
104
|
+
)
|
105
|
+
|
106
|
+
|
69
107
|
@router.get(
|
70
108
|
"",
|
71
|
-
response_model=Page[SecretResponse],
|
72
109
|
responses={401: error_response, 404: error_response, 422: error_response},
|
73
110
|
)
|
74
111
|
@handle_exceptions
|
@@ -116,7 +153,6 @@ def list_secrets(
|
|
116
153
|
|
117
154
|
@router.get(
|
118
155
|
"/{secret_id}",
|
119
|
-
response_model=SecretResponse,
|
120
156
|
responses={401: error_response, 404: error_response, 422: error_response},
|
121
157
|
)
|
122
158
|
@handle_exceptions
|
@@ -140,6 +176,7 @@ def get_secret(
|
|
140
176
|
get_method=zen_store().get_secret,
|
141
177
|
hydrate=hydrate,
|
142
178
|
)
|
179
|
+
|
143
180
|
if not has_permissions_for_model(secret, action=Action.READ_SECRET_VALUE):
|
144
181
|
secret.remove_secrets()
|
145
182
|
|
@@ -148,7 +185,6 @@ def get_secret(
|
|
148
185
|
|
149
186
|
@router.put(
|
150
187
|
"/{secret_id}",
|
151
|
-
response_model=SecretResponse,
|
152
188
|
responses={401: error_response, 404: error_response, 422: error_response},
|
153
189
|
)
|
154
190
|
@handle_exceptions
|
@@ -25,20 +25,27 @@ from zenml.constants import (
|
|
25
25
|
LOAD_INFO,
|
26
26
|
ONBOARDING_STATE,
|
27
27
|
SERVER_SETTINGS,
|
28
|
+
STATISTICS,
|
28
29
|
VERSION_1,
|
29
30
|
)
|
30
31
|
from zenml.enums import AuthScheme
|
31
32
|
from zenml.exceptions import IllegalOperationError
|
32
33
|
from zenml.models import (
|
34
|
+
ComponentFilter,
|
33
35
|
ServerActivationRequest,
|
34
36
|
ServerLoadInfo,
|
35
37
|
ServerModel,
|
36
38
|
ServerSettingsResponse,
|
37
39
|
ServerSettingsUpdate,
|
40
|
+
ServerStatistics,
|
41
|
+
StackFilter,
|
38
42
|
UserResponse,
|
43
|
+
WorkspaceFilter,
|
39
44
|
)
|
40
45
|
from zenml.zen_server.auth import AuthContext, authorize
|
41
46
|
from zenml.zen_server.exceptions import error_response
|
47
|
+
from zenml.zen_server.rbac.models import ResourceType
|
48
|
+
from zenml.zen_server.rbac.utils import get_allowed_resource_ids
|
42
49
|
from zenml.zen_server.utils import handle_exceptions, server_config, zen_store
|
43
50
|
|
44
51
|
router = APIRouter(
|
@@ -60,7 +67,6 @@ def version() -> str:
|
|
60
67
|
|
61
68
|
@router.get(
|
62
69
|
INFO,
|
63
|
-
response_model=ServerModel,
|
64
70
|
responses={401: error_response, 404: error_response, 422: error_response},
|
65
71
|
)
|
66
72
|
@handle_exceptions
|
@@ -234,3 +240,49 @@ if server_config().auth_scheme != AuthScheme.EXTERNAL:
|
|
234
240
|
The default admin user that was created during activation, if any.
|
235
241
|
"""
|
236
242
|
return zen_store().activate_server(activate_request)
|
243
|
+
|
244
|
+
|
245
|
+
@router.get(
|
246
|
+
STATISTICS,
|
247
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
248
|
+
)
|
249
|
+
@handle_exceptions
|
250
|
+
def get_server_statistics(
|
251
|
+
auth_context: AuthContext = Security(authorize),
|
252
|
+
) -> ServerStatistics:
|
253
|
+
"""Gets server statistics.
|
254
|
+
|
255
|
+
Args:
|
256
|
+
auth_context: Authentication context.
|
257
|
+
|
258
|
+
Returns:
|
259
|
+
Statistics of the server.
|
260
|
+
"""
|
261
|
+
user_id = auth_context.user.id
|
262
|
+
component_filter = ComponentFilter()
|
263
|
+
component_filter.configure_rbac(
|
264
|
+
authenticated_user_id=user_id,
|
265
|
+
id=get_allowed_resource_ids(
|
266
|
+
resource_type=ResourceType.STACK_COMPONENT
|
267
|
+
),
|
268
|
+
)
|
269
|
+
|
270
|
+
workspace_filter = WorkspaceFilter()
|
271
|
+
workspace_filter.configure_rbac(
|
272
|
+
authenticated_user_id=user_id,
|
273
|
+
id=get_allowed_resource_ids(resource_type=ResourceType.WORKSPACE),
|
274
|
+
)
|
275
|
+
|
276
|
+
stack_filter = StackFilter()
|
277
|
+
stack_filter.configure_rbac(
|
278
|
+
authenticated_user_id=user_id,
|
279
|
+
id=get_allowed_resource_ids(resource_type=ResourceType.STACK),
|
280
|
+
)
|
281
|
+
|
282
|
+
return ServerStatistics(
|
283
|
+
stacks=zen_store().count_stacks(filter_model=stack_filter),
|
284
|
+
components=zen_store().count_stack_components(
|
285
|
+
filter_model=component_filter
|
286
|
+
),
|
287
|
+
workspaces=zen_store().count_workspaces(filter_model=workspace_filter),
|
288
|
+
)
|