zenml-nightly 0.75.0.dev20250311__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 +618 -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_build.py +18 -0
- 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 +4 -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/0392807467dc_add_build_duration.py +34 -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/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_build_schemas.py +4 -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.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/METADATA +1 -1
- {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/RECORD +163 -149
- {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250311.dist-info → zenml_nightly-0.75.0.dev20250313.dist-info}/entry_points.txt +0 -0
@@ -13,118 +13,55 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for workspaces."""
|
15
15
|
|
16
|
-
from typing import
|
16
|
+
from typing import Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
20
20
|
|
21
21
|
from zenml.constants import (
|
22
22
|
API,
|
23
|
-
CODE_REPOSITORIES,
|
24
|
-
GET_OR_CREATE,
|
25
|
-
MODEL_VERSIONS,
|
26
|
-
MODELS,
|
27
|
-
PIPELINE_BUILDS,
|
28
|
-
PIPELINE_DEPLOYMENTS,
|
29
|
-
PIPELINES,
|
30
|
-
RUN_METADATA,
|
31
|
-
RUN_TEMPLATES,
|
32
|
-
RUNS,
|
33
|
-
SCHEDULES,
|
34
|
-
SECRETS,
|
35
|
-
SERVICE_CONNECTOR_RESOURCES,
|
36
|
-
SERVICE_CONNECTORS,
|
37
|
-
SERVICES,
|
38
|
-
STACK_COMPONENTS,
|
39
|
-
STACKS,
|
40
23
|
STATISTICS,
|
41
24
|
VERSION_1,
|
42
25
|
WORKSPACES,
|
43
26
|
)
|
44
|
-
from zenml.enums import MetadataResourceTypes
|
45
|
-
from zenml.exceptions import IllegalOperationError
|
46
27
|
from zenml.models import (
|
47
|
-
CodeRepositoryFilter,
|
48
|
-
CodeRepositoryRequest,
|
49
|
-
CodeRepositoryResponse,
|
50
|
-
ComponentFilter,
|
51
|
-
ComponentRequest,
|
52
|
-
ComponentResponse,
|
53
|
-
ModelRequest,
|
54
|
-
ModelResponse,
|
55
|
-
ModelVersionRequest,
|
56
|
-
ModelVersionResponse,
|
57
28
|
Page,
|
58
|
-
PipelineBuildFilter,
|
59
|
-
PipelineBuildRequest,
|
60
|
-
PipelineBuildResponse,
|
61
|
-
PipelineDeploymentFilter,
|
62
|
-
PipelineDeploymentRequest,
|
63
|
-
PipelineDeploymentResponse,
|
64
29
|
PipelineFilter,
|
65
|
-
PipelineRequest,
|
66
|
-
PipelineResponse,
|
67
30
|
PipelineRunFilter,
|
68
|
-
PipelineRunRequest,
|
69
|
-
PipelineRunResponse,
|
70
|
-
RunMetadataRequest,
|
71
|
-
RunTemplateFilter,
|
72
|
-
RunTemplateRequest,
|
73
|
-
RunTemplateResponse,
|
74
|
-
ScheduleRequest,
|
75
|
-
ScheduleResponse,
|
76
|
-
SecretRequest,
|
77
|
-
SecretResponse,
|
78
|
-
ServiceConnectorFilter,
|
79
|
-
ServiceConnectorRequest,
|
80
|
-
ServiceConnectorResourcesModel,
|
81
|
-
ServiceConnectorResponse,
|
82
|
-
ServiceRequest,
|
83
|
-
ServiceResponse,
|
84
|
-
StackFilter,
|
85
|
-
StackRequest,
|
86
|
-
StackResponse,
|
87
31
|
WorkspaceFilter,
|
88
32
|
WorkspaceRequest,
|
89
33
|
WorkspaceResponse,
|
34
|
+
WorkspaceStatistics,
|
90
35
|
WorkspaceUpdate,
|
91
36
|
)
|
92
37
|
from zenml.zen_server.auth import AuthContext, authorize
|
93
38
|
from zenml.zen_server.exceptions import error_response
|
94
|
-
from zenml.zen_server.feature_gate.endpoint_utils import (
|
95
|
-
check_entitlement,
|
96
|
-
report_usage,
|
97
|
-
)
|
98
39
|
from zenml.zen_server.rbac.endpoint_utils import (
|
99
40
|
verify_permissions_and_create_entity,
|
41
|
+
verify_permissions_and_delete_entity,
|
42
|
+
verify_permissions_and_get_entity,
|
100
43
|
verify_permissions_and_list_entities,
|
44
|
+
verify_permissions_and_update_entity,
|
101
45
|
)
|
102
|
-
from zenml.zen_server.rbac.models import
|
46
|
+
from zenml.zen_server.rbac.models import ResourceType
|
103
47
|
from zenml.zen_server.rbac.utils import (
|
104
|
-
batch_verify_permissions_for_models,
|
105
|
-
dehydrate_page,
|
106
|
-
dehydrate_response_model,
|
107
48
|
get_allowed_resource_ids,
|
108
|
-
verify_permission,
|
109
|
-
verify_permission_for_model,
|
110
49
|
)
|
111
50
|
from zenml.zen_server.utils import (
|
112
51
|
handle_exceptions,
|
113
52
|
make_dependable,
|
114
|
-
server_config,
|
115
53
|
zen_store,
|
116
54
|
)
|
117
55
|
|
118
56
|
router = APIRouter(
|
119
|
-
prefix=API + VERSION_1,
|
57
|
+
prefix=API + VERSION_1 + WORKSPACES,
|
120
58
|
tags=["workspaces"],
|
121
59
|
responses={401: error_response},
|
122
60
|
)
|
123
61
|
|
124
62
|
|
125
63
|
@router.get(
|
126
|
-
|
127
|
-
response_model=Page[WorkspaceResponse],
|
64
|
+
"",
|
128
65
|
responses={401: error_response, 404: error_response, 422: error_response},
|
129
66
|
)
|
130
67
|
@handle_exceptions
|
@@ -146,14 +83,16 @@ def list_workspaces(
|
|
146
83
|
Returns:
|
147
84
|
A list of workspaces.
|
148
85
|
"""
|
149
|
-
|
150
|
-
workspace_filter_model,
|
86
|
+
return verify_permissions_and_list_entities(
|
87
|
+
filter_model=workspace_filter_model,
|
88
|
+
resource_type=ResourceType.WORKSPACE,
|
89
|
+
list_method=zen_store().list_workspaces,
|
90
|
+
hydrate=hydrate,
|
151
91
|
)
|
152
|
-
return dehydrate_page(workspaces)
|
153
92
|
|
154
93
|
|
155
94
|
@router.post(
|
156
|
-
|
95
|
+
"",
|
157
96
|
responses={401: error_response, 409: error_response, 422: error_response},
|
158
97
|
)
|
159
98
|
@handle_exceptions
|
@@ -171,13 +110,14 @@ def create_workspace(
|
|
171
110
|
Returns:
|
172
111
|
The created workspace.
|
173
112
|
"""
|
174
|
-
|
175
|
-
|
113
|
+
return verify_permissions_and_create_entity(
|
114
|
+
request_model=workspace_request,
|
115
|
+
create_method=zen_store().create_workspace,
|
116
|
+
)
|
176
117
|
|
177
118
|
|
178
119
|
@router.get(
|
179
|
-
|
180
|
-
response_model=WorkspaceResponse,
|
120
|
+
"/{workspace_name_or_id}",
|
181
121
|
responses={401: error_response, 404: error_response, 422: error_response},
|
182
122
|
)
|
183
123
|
@handle_exceptions
|
@@ -198,14 +138,15 @@ def get_workspace(
|
|
198
138
|
Returns:
|
199
139
|
The requested workspace.
|
200
140
|
"""
|
201
|
-
|
202
|
-
workspace_name_or_id,
|
141
|
+
return verify_permissions_and_get_entity(
|
142
|
+
id=workspace_name_or_id,
|
143
|
+
get_method=zen_store().get_workspace,
|
144
|
+
hydrate=hydrate,
|
203
145
|
)
|
204
|
-
return dehydrate_response_model(workspace)
|
205
146
|
|
206
147
|
|
207
148
|
@router.put(
|
208
|
-
|
149
|
+
"/{workspace_name_or_id}",
|
209
150
|
responses={401: error_response, 404: error_response, 422: error_response},
|
210
151
|
)
|
211
152
|
@handle_exceptions
|
@@ -225,15 +166,16 @@ def update_workspace(
|
|
225
166
|
Returns:
|
226
167
|
The updated workspace.
|
227
168
|
"""
|
228
|
-
|
229
|
-
|
230
|
-
|
169
|
+
return verify_permissions_and_update_entity(
|
170
|
+
id=workspace_name_or_id,
|
171
|
+
update_model=workspace_update,
|
172
|
+
get_method=zen_store().get_workspace,
|
173
|
+
update_method=zen_store().update_workspace,
|
231
174
|
)
|
232
|
-
return dehydrate_response_model(updated_workspace)
|
233
175
|
|
234
176
|
|
235
177
|
@router.delete(
|
236
|
-
|
178
|
+
"/{workspace_name_or_id}",
|
237
179
|
responses={401: error_response, 404: error_response, 422: error_response},
|
238
180
|
)
|
239
181
|
@handle_exceptions
|
@@ -246,1224 +188,53 @@ def delete_workspace(
|
|
246
188
|
Args:
|
247
189
|
workspace_name_or_id: Name or ID of the workspace.
|
248
190
|
"""
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
WORKSPACES + "/{workspace_name_or_id}" + STACKS,
|
254
|
-
response_model=Page[StackResponse],
|
255
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
256
|
-
)
|
257
|
-
@handle_exceptions
|
258
|
-
def list_workspace_stacks(
|
259
|
-
workspace_name_or_id: Union[str, UUID],
|
260
|
-
stack_filter_model: StackFilter = Depends(make_dependable(StackFilter)),
|
261
|
-
hydrate: bool = False,
|
262
|
-
_: AuthContext = Security(authorize),
|
263
|
-
) -> Page[StackResponse]:
|
264
|
-
"""Get stacks that are part of a specific workspace for the user.
|
265
|
-
|
266
|
-
# noqa: DAR401
|
267
|
-
|
268
|
-
Args:
|
269
|
-
workspace_name_or_id: Name or ID of the workspace.
|
270
|
-
stack_filter_model: Filter model used for pagination, sorting,
|
271
|
-
filtering.
|
272
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
273
|
-
by including metadata fields in the response.
|
274
|
-
|
275
|
-
Returns:
|
276
|
-
All stacks part of the specified workspace.
|
277
|
-
"""
|
278
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
279
|
-
stack_filter_model.set_scope_workspace(workspace.id)
|
280
|
-
|
281
|
-
return verify_permissions_and_list_entities(
|
282
|
-
filter_model=stack_filter_model,
|
283
|
-
resource_type=ResourceType.STACK,
|
284
|
-
list_method=zen_store().list_stacks,
|
285
|
-
hydrate=hydrate,
|
286
|
-
)
|
287
|
-
|
288
|
-
|
289
|
-
@router.post(
|
290
|
-
WORKSPACES + "/{workspace_name_or_id}" + STACKS,
|
291
|
-
response_model=StackResponse,
|
292
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
293
|
-
)
|
294
|
-
@handle_exceptions
|
295
|
-
def create_stack(
|
296
|
-
workspace_name_or_id: Union[str, UUID],
|
297
|
-
stack: StackRequest,
|
298
|
-
auth_context: AuthContext = Security(authorize),
|
299
|
-
) -> StackResponse:
|
300
|
-
"""Creates a stack for a particular workspace.
|
301
|
-
|
302
|
-
Args:
|
303
|
-
workspace_name_or_id: Name or ID of the workspace.
|
304
|
-
stack: Stack to register.
|
305
|
-
auth_context: Authentication context.
|
306
|
-
|
307
|
-
Returns:
|
308
|
-
The created stack.
|
309
|
-
"""
|
310
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
311
|
-
|
312
|
-
# Check the service connector creation
|
313
|
-
is_connector_create_needed = False
|
314
|
-
for connector_id_or_info in stack.service_connectors:
|
315
|
-
if isinstance(connector_id_or_info, UUID):
|
316
|
-
service_connector = zen_store().get_service_connector(
|
317
|
-
connector_id_or_info, hydrate=False
|
318
|
-
)
|
319
|
-
verify_permission_for_model(
|
320
|
-
model=service_connector, action=Action.READ
|
321
|
-
)
|
322
|
-
else:
|
323
|
-
is_connector_create_needed = True
|
324
|
-
|
325
|
-
# Check the component creation
|
326
|
-
if is_connector_create_needed:
|
327
|
-
verify_permission(
|
328
|
-
resource_type=ResourceType.SERVICE_CONNECTOR, action=Action.CREATE
|
329
|
-
)
|
330
|
-
is_component_create_needed = False
|
331
|
-
for components in stack.components.values():
|
332
|
-
for component_id_or_info in components:
|
333
|
-
if isinstance(component_id_or_info, UUID):
|
334
|
-
component = zen_store().get_stack_component(
|
335
|
-
component_id_or_info, hydrate=False
|
336
|
-
)
|
337
|
-
verify_permission_for_model(
|
338
|
-
model=component, action=Action.READ
|
339
|
-
)
|
340
|
-
else:
|
341
|
-
is_component_create_needed = True
|
342
|
-
if is_component_create_needed:
|
343
|
-
verify_permission(
|
344
|
-
resource_type=ResourceType.STACK_COMPONENT,
|
345
|
-
action=Action.CREATE,
|
346
|
-
)
|
347
|
-
|
348
|
-
# Check the stack creation
|
349
|
-
verify_permission(resource_type=ResourceType.STACK, action=Action.CREATE)
|
350
|
-
|
351
|
-
stack.user = auth_context.user.id
|
352
|
-
stack.workspace = workspace.id
|
353
|
-
|
354
|
-
return zen_store().create_stack(stack)
|
355
|
-
|
356
|
-
|
357
|
-
@router.get(
|
358
|
-
WORKSPACES + "/{workspace_name_or_id}" + STACK_COMPONENTS,
|
359
|
-
response_model=Page[ComponentResponse],
|
360
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
361
|
-
)
|
362
|
-
@handle_exceptions
|
363
|
-
def list_workspace_stack_components(
|
364
|
-
workspace_name_or_id: Union[str, UUID],
|
365
|
-
component_filter_model: ComponentFilter = Depends(
|
366
|
-
make_dependable(ComponentFilter)
|
367
|
-
),
|
368
|
-
hydrate: bool = False,
|
369
|
-
_: AuthContext = Security(authorize),
|
370
|
-
) -> Page[ComponentResponse]:
|
371
|
-
"""List stack components that are part of a specific workspace.
|
372
|
-
|
373
|
-
# noqa: DAR401
|
374
|
-
|
375
|
-
Args:
|
376
|
-
workspace_name_or_id: Name or ID of the workspace.
|
377
|
-
component_filter_model: Filter model used for pagination, sorting,
|
378
|
-
filtering.
|
379
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
380
|
-
by including metadata fields in the response.
|
381
|
-
|
382
|
-
Returns:
|
383
|
-
All stack components part of the specified workspace.
|
384
|
-
"""
|
385
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
386
|
-
component_filter_model.set_scope_workspace(workspace.id)
|
387
|
-
|
388
|
-
return verify_permissions_and_list_entities(
|
389
|
-
filter_model=component_filter_model,
|
390
|
-
resource_type=ResourceType.STACK_COMPONENT,
|
391
|
-
list_method=zen_store().list_stack_components,
|
392
|
-
hydrate=hydrate,
|
393
|
-
)
|
394
|
-
|
395
|
-
|
396
|
-
@router.post(
|
397
|
-
WORKSPACES + "/{workspace_name_or_id}" + STACK_COMPONENTS,
|
398
|
-
response_model=ComponentResponse,
|
399
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
400
|
-
)
|
401
|
-
@handle_exceptions
|
402
|
-
def create_stack_component(
|
403
|
-
workspace_name_or_id: Union[str, UUID],
|
404
|
-
component: ComponentRequest,
|
405
|
-
_: AuthContext = Security(authorize),
|
406
|
-
) -> ComponentResponse:
|
407
|
-
"""Creates a stack component.
|
408
|
-
|
409
|
-
Args:
|
410
|
-
workspace_name_or_id: Name or ID of the workspace.
|
411
|
-
component: Stack component to register.
|
412
|
-
|
413
|
-
Returns:
|
414
|
-
The created stack component.
|
415
|
-
|
416
|
-
Raises:
|
417
|
-
IllegalOperationError: If the workspace specified in the stack
|
418
|
-
component does not match the current workspace.
|
419
|
-
"""
|
420
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
421
|
-
|
422
|
-
if component.workspace != workspace.id:
|
423
|
-
raise IllegalOperationError(
|
424
|
-
"Creating components outside of the workspace scope "
|
425
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
426
|
-
f"not supported."
|
427
|
-
)
|
428
|
-
|
429
|
-
if component.connector:
|
430
|
-
service_connector = zen_store().get_service_connector(
|
431
|
-
component.connector
|
432
|
-
)
|
433
|
-
verify_permission_for_model(service_connector, action=Action.READ)
|
434
|
-
|
435
|
-
from zenml.stack.utils import validate_stack_component_config
|
436
|
-
|
437
|
-
validate_stack_component_config(
|
438
|
-
configuration_dict=component.configuration,
|
439
|
-
flavor=component.flavor,
|
440
|
-
component_type=component.type,
|
441
|
-
zen_store=zen_store(),
|
442
|
-
# We allow custom flavors to fail import on the server side.
|
443
|
-
validate_custom_flavors=False,
|
444
|
-
)
|
445
|
-
|
446
|
-
return verify_permissions_and_create_entity(
|
447
|
-
request_model=component,
|
448
|
-
resource_type=ResourceType.STACK_COMPONENT,
|
449
|
-
create_method=zen_store().create_stack_component,
|
450
|
-
)
|
451
|
-
|
452
|
-
|
453
|
-
@router.get(
|
454
|
-
WORKSPACES + "/{workspace_name_or_id}" + PIPELINES,
|
455
|
-
response_model=Page[PipelineResponse],
|
456
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
457
|
-
)
|
458
|
-
@handle_exceptions
|
459
|
-
def list_workspace_pipelines(
|
460
|
-
workspace_name_or_id: Union[str, UUID],
|
461
|
-
pipeline_filter_model: PipelineFilter = Depends(
|
462
|
-
make_dependable(PipelineFilter)
|
463
|
-
),
|
464
|
-
hydrate: bool = False,
|
465
|
-
_: AuthContext = Security(authorize),
|
466
|
-
) -> Page[PipelineResponse]:
|
467
|
-
"""Gets pipelines defined for a specific workspace.
|
468
|
-
|
469
|
-
# noqa: DAR401
|
470
|
-
|
471
|
-
Args:
|
472
|
-
workspace_name_or_id: Name or ID of the workspace.
|
473
|
-
pipeline_filter_model: Filter model used for pagination, sorting,
|
474
|
-
filtering.
|
475
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
476
|
-
by including metadata fields in the response.
|
477
|
-
|
478
|
-
Returns:
|
479
|
-
All pipelines within the workspace.
|
480
|
-
"""
|
481
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
482
|
-
pipeline_filter_model.set_scope_workspace(workspace.id)
|
483
|
-
|
484
|
-
return verify_permissions_and_list_entities(
|
485
|
-
filter_model=pipeline_filter_model,
|
486
|
-
resource_type=ResourceType.PIPELINE,
|
487
|
-
list_method=zen_store().list_pipelines,
|
488
|
-
hydrate=hydrate,
|
489
|
-
)
|
490
|
-
|
491
|
-
|
492
|
-
@router.post(
|
493
|
-
WORKSPACES + "/{workspace_name_or_id}" + PIPELINES,
|
494
|
-
response_model=PipelineResponse,
|
495
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
496
|
-
)
|
497
|
-
@handle_exceptions
|
498
|
-
def create_pipeline(
|
499
|
-
workspace_name_or_id: Union[str, UUID],
|
500
|
-
pipeline: PipelineRequest,
|
501
|
-
_: AuthContext = Security(authorize),
|
502
|
-
) -> PipelineResponse:
|
503
|
-
"""Creates a pipeline.
|
504
|
-
|
505
|
-
Args:
|
506
|
-
workspace_name_or_id: Name or ID of the workspace.
|
507
|
-
pipeline: Pipeline to create.
|
508
|
-
|
509
|
-
Returns:
|
510
|
-
The created pipeline.
|
511
|
-
|
512
|
-
Raises:
|
513
|
-
IllegalOperationError: If the workspace or user specified in the pipeline
|
514
|
-
does not match the current workspace or authenticated user.
|
515
|
-
"""
|
516
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
517
|
-
|
518
|
-
if pipeline.workspace != workspace.id:
|
519
|
-
raise IllegalOperationError(
|
520
|
-
"Creating pipelines outside of the workspace scope "
|
521
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
522
|
-
f"not supported."
|
523
|
-
)
|
524
|
-
|
525
|
-
# We limit pipeline namespaces, not pipeline versions
|
526
|
-
needs_usage_increment = (
|
527
|
-
ResourceType.PIPELINE in server_config().reportable_resources
|
528
|
-
and zen_store().count_pipelines(PipelineFilter(name=pipeline.name))
|
529
|
-
== 0
|
191
|
+
verify_permissions_and_delete_entity(
|
192
|
+
id=workspace_name_or_id,
|
193
|
+
get_method=zen_store().get_workspace,
|
194
|
+
delete_method=zen_store().delete_workspace,
|
530
195
|
)
|
531
196
|
|
532
|
-
if needs_usage_increment:
|
533
|
-
check_entitlement(ResourceType.PIPELINE)
|
534
|
-
|
535
|
-
pipeline_response = verify_permissions_and_create_entity(
|
536
|
-
request_model=pipeline,
|
537
|
-
resource_type=ResourceType.PIPELINE,
|
538
|
-
create_method=zen_store().create_pipeline,
|
539
|
-
)
|
540
|
-
|
541
|
-
if needs_usage_increment:
|
542
|
-
report_usage(
|
543
|
-
resource_type=ResourceType.PIPELINE,
|
544
|
-
resource_id=pipeline_response.id,
|
545
|
-
)
|
546
|
-
|
547
|
-
return pipeline_response
|
548
|
-
|
549
197
|
|
550
198
|
@router.get(
|
551
|
-
|
552
|
-
response_model=Page[PipelineBuildResponse],
|
199
|
+
"/{workspace_name_or_id}" + STATISTICS,
|
553
200
|
responses={401: error_response, 404: error_response, 422: error_response},
|
554
201
|
)
|
555
202
|
@handle_exceptions
|
556
|
-
def
|
557
|
-
workspace_name_or_id: Union[str, UUID],
|
558
|
-
build_filter_model: PipelineBuildFilter = Depends(
|
559
|
-
make_dependable(PipelineBuildFilter)
|
560
|
-
),
|
561
|
-
hydrate: bool = False,
|
562
|
-
_: AuthContext = Security(authorize),
|
563
|
-
) -> Page[PipelineBuildResponse]:
|
564
|
-
"""Gets builds defined for a specific workspace.
|
565
|
-
|
566
|
-
# noqa: DAR401
|
567
|
-
|
568
|
-
Args:
|
569
|
-
workspace_name_or_id: Name or ID of the workspace.
|
570
|
-
build_filter_model: Filter model used for pagination, sorting,
|
571
|
-
filtering.
|
572
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
573
|
-
by including metadata fields in the response.
|
574
|
-
|
575
|
-
Returns:
|
576
|
-
All builds within the workspace.
|
577
|
-
"""
|
578
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
579
|
-
build_filter_model.set_scope_workspace(workspace.id)
|
580
|
-
|
581
|
-
return verify_permissions_and_list_entities(
|
582
|
-
filter_model=build_filter_model,
|
583
|
-
resource_type=ResourceType.PIPELINE_BUILD,
|
584
|
-
list_method=zen_store().list_builds,
|
585
|
-
hydrate=hydrate,
|
586
|
-
)
|
587
|
-
|
588
|
-
|
589
|
-
@router.post(
|
590
|
-
WORKSPACES + "/{workspace_name_or_id}" + PIPELINE_BUILDS,
|
591
|
-
response_model=PipelineBuildResponse,
|
592
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
593
|
-
)
|
594
|
-
@handle_exceptions
|
595
|
-
def create_build(
|
203
|
+
def get_workspace_statistics(
|
596
204
|
workspace_name_or_id: Union[str, UUID],
|
597
|
-
build: PipelineBuildRequest,
|
598
205
|
auth_context: AuthContext = Security(authorize),
|
599
|
-
) ->
|
600
|
-
"""
|
601
|
-
|
602
|
-
Args:
|
603
|
-
workspace_name_or_id: Name or ID of the workspace.
|
604
|
-
build: Build to create.
|
605
|
-
auth_context: Authentication context.
|
606
|
-
|
607
|
-
Returns:
|
608
|
-
The created build.
|
609
|
-
|
610
|
-
Raises:
|
611
|
-
IllegalOperationError: If the workspace specified in the build
|
612
|
-
does not match the current workspace.
|
613
|
-
"""
|
614
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
615
|
-
|
616
|
-
if build.workspace != workspace.id:
|
617
|
-
raise IllegalOperationError(
|
618
|
-
"Creating builds outside of the workspace scope "
|
619
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
620
|
-
f"not supported."
|
621
|
-
)
|
622
|
-
|
623
|
-
return verify_permissions_and_create_entity(
|
624
|
-
request_model=build,
|
625
|
-
resource_type=ResourceType.PIPELINE_BUILD,
|
626
|
-
create_method=zen_store().create_build,
|
627
|
-
)
|
628
|
-
|
629
|
-
|
630
|
-
@router.get(
|
631
|
-
WORKSPACES + "/{workspace_name_or_id}" + PIPELINE_DEPLOYMENTS,
|
632
|
-
response_model=Page[PipelineDeploymentResponse],
|
633
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
634
|
-
)
|
635
|
-
@handle_exceptions
|
636
|
-
def list_workspace_deployments(
|
637
|
-
workspace_name_or_id: Union[str, UUID],
|
638
|
-
deployment_filter_model: PipelineDeploymentFilter = Depends(
|
639
|
-
make_dependable(PipelineDeploymentFilter)
|
640
|
-
),
|
641
|
-
hydrate: bool = False,
|
642
|
-
_: AuthContext = Security(authorize),
|
643
|
-
) -> Page[PipelineDeploymentResponse]:
|
644
|
-
"""Gets deployments defined for a specific workspace.
|
206
|
+
) -> WorkspaceStatistics:
|
207
|
+
"""Gets statistics of a workspace.
|
645
208
|
|
646
209
|
# noqa: DAR401
|
647
210
|
|
648
211
|
Args:
|
649
|
-
workspace_name_or_id: Name or ID of the workspace.
|
650
|
-
deployment_filter_model: Filter model used for pagination, sorting,
|
651
|
-
filtering.
|
652
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
653
|
-
by including metadata fields in the response.
|
654
|
-
|
655
|
-
Returns:
|
656
|
-
All deployments within the workspace.
|
657
|
-
"""
|
658
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
659
|
-
deployment_filter_model.set_scope_workspace(workspace.id)
|
660
|
-
|
661
|
-
return verify_permissions_and_list_entities(
|
662
|
-
filter_model=deployment_filter_model,
|
663
|
-
resource_type=ResourceType.PIPELINE_DEPLOYMENT,
|
664
|
-
list_method=zen_store().list_deployments,
|
665
|
-
hydrate=hydrate,
|
666
|
-
)
|
667
|
-
|
668
|
-
|
669
|
-
@router.post(
|
670
|
-
WORKSPACES + "/{workspace_name_or_id}" + PIPELINE_DEPLOYMENTS,
|
671
|
-
response_model=PipelineDeploymentResponse,
|
672
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
673
|
-
)
|
674
|
-
@handle_exceptions
|
675
|
-
def create_deployment(
|
676
|
-
workspace_name_or_id: Union[str, UUID],
|
677
|
-
deployment: PipelineDeploymentRequest,
|
678
|
-
auth_context: AuthContext = Security(authorize),
|
679
|
-
) -> PipelineDeploymentResponse:
|
680
|
-
"""Creates a deployment.
|
681
|
-
|
682
|
-
Args:
|
683
|
-
workspace_name_or_id: Name or ID of the workspace.
|
684
|
-
deployment: Deployment to create.
|
212
|
+
workspace_name_or_id: Name or ID of the workspace to get statistics for.
|
685
213
|
auth_context: Authentication context.
|
686
214
|
|
687
215
|
Returns:
|
688
|
-
|
689
|
-
|
690
|
-
Raises:
|
691
|
-
IllegalOperationError: If the workspace specified in the
|
692
|
-
deployment does not match the current workspace.
|
216
|
+
All pipelines within the workspace.
|
693
217
|
"""
|
694
|
-
workspace =
|
695
|
-
|
696
|
-
|
697
|
-
raise IllegalOperationError(
|
698
|
-
"Creating deployments outside of the workspace scope "
|
699
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
700
|
-
f"not supported."
|
701
|
-
)
|
702
|
-
|
703
|
-
return verify_permissions_and_create_entity(
|
704
|
-
request_model=deployment,
|
705
|
-
resource_type=ResourceType.PIPELINE_DEPLOYMENT,
|
706
|
-
create_method=zen_store().create_deployment,
|
218
|
+
workspace = verify_permissions_and_get_entity(
|
219
|
+
id=workspace_name_or_id,
|
220
|
+
get_method=zen_store().get_workspace,
|
707
221
|
)
|
708
222
|
|
223
|
+
user_id = auth_context.user.id
|
709
224
|
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
)
|
714
|
-
@handle_exceptions
|
715
|
-
def list_workspace_run_templates(
|
716
|
-
workspace_name_or_id: Union[str, UUID],
|
717
|
-
filter_model: RunTemplateFilter = Depends(
|
718
|
-
make_dependable(RunTemplateFilter)
|
719
|
-
),
|
720
|
-
hydrate: bool = False,
|
721
|
-
_: AuthContext = Security(authorize),
|
722
|
-
) -> Page[RunTemplateResponse]:
|
723
|
-
"""Get a page of run templates.
|
724
|
-
|
725
|
-
Args:
|
726
|
-
workspace_name_or_id: Name or ID of the workspace.
|
727
|
-
filter_model: Filter model used for pagination, sorting,
|
728
|
-
filtering.
|
729
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
730
|
-
by including metadata fields in the response.
|
731
|
-
|
732
|
-
Returns:
|
733
|
-
Page of run templates.
|
734
|
-
"""
|
735
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
736
|
-
filter_model.set_scope_workspace(workspace.id)
|
737
|
-
|
738
|
-
return verify_permissions_and_list_entities(
|
739
|
-
filter_model=filter_model,
|
740
|
-
resource_type=ResourceType.RUN_TEMPLATE,
|
741
|
-
list_method=zen_store().list_run_templates,
|
742
|
-
hydrate=hydrate,
|
225
|
+
run_filter = PipelineRunFilter(workspace=workspace.id)
|
226
|
+
run_filter.configure_rbac(
|
227
|
+
authenticated_user_id=user_id,
|
228
|
+
id=get_allowed_resource_ids(resource_type=ResourceType.PIPELINE_RUN),
|
743
229
|
)
|
744
230
|
|
231
|
+
pipeline_filter = PipelineFilter(workspace=workspace.id)
|
232
|
+
pipeline_filter.configure_rbac(
|
233
|
+
authenticated_user_id=user_id,
|
234
|
+
id=get_allowed_resource_ids(resource_type=ResourceType.PIPELINE),
|
235
|
+
)
|
745
236
|
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
)
|
750
|
-
@handle_exceptions
|
751
|
-
def create_run_template(
|
752
|
-
workspace_name_or_id: Union[str, UUID],
|
753
|
-
run_template: RunTemplateRequest,
|
754
|
-
_: AuthContext = Security(authorize),
|
755
|
-
) -> RunTemplateResponse:
|
756
|
-
"""Create a run template.
|
757
|
-
|
758
|
-
Args:
|
759
|
-
workspace_name_or_id: Name or ID of the workspace.
|
760
|
-
run_template: Run template to create.
|
761
|
-
|
762
|
-
Returns:
|
763
|
-
The created run template.
|
764
|
-
|
765
|
-
Raises:
|
766
|
-
IllegalOperationError: If the workspace specified in the
|
767
|
-
run template does not match the current workspace.
|
768
|
-
"""
|
769
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
770
|
-
|
771
|
-
if run_template.workspace != workspace.id:
|
772
|
-
raise IllegalOperationError(
|
773
|
-
"Creating run templates outside of the workspace scope "
|
774
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
775
|
-
f"not supported."
|
776
|
-
)
|
777
|
-
|
778
|
-
return verify_permissions_and_create_entity(
|
779
|
-
request_model=run_template,
|
780
|
-
resource_type=ResourceType.RUN_TEMPLATE,
|
781
|
-
create_method=zen_store().create_run_template,
|
782
|
-
)
|
783
|
-
|
784
|
-
|
785
|
-
@router.get(
|
786
|
-
WORKSPACES + "/{workspace_name_or_id}" + RUNS,
|
787
|
-
response_model=Page[PipelineRunResponse],
|
788
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
789
|
-
)
|
790
|
-
@handle_exceptions
|
791
|
-
def list_runs(
|
792
|
-
workspace_name_or_id: Union[str, UUID],
|
793
|
-
runs_filter_model: PipelineRunFilter = Depends(
|
794
|
-
make_dependable(PipelineRunFilter)
|
795
|
-
),
|
796
|
-
hydrate: bool = False,
|
797
|
-
_: AuthContext = Security(authorize),
|
798
|
-
) -> Page[PipelineRunResponse]:
|
799
|
-
"""Get pipeline runs according to query filters.
|
800
|
-
|
801
|
-
Args:
|
802
|
-
workspace_name_or_id: Name or ID of the workspace.
|
803
|
-
runs_filter_model: Filter model used for pagination, sorting,
|
804
|
-
filtering.
|
805
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
806
|
-
by including metadata fields in the response.
|
807
|
-
|
808
|
-
Returns:
|
809
|
-
The pipeline runs according to query filters.
|
810
|
-
"""
|
811
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
812
|
-
runs_filter_model.set_scope_workspace(workspace.id)
|
813
|
-
|
814
|
-
return verify_permissions_and_list_entities(
|
815
|
-
filter_model=runs_filter_model,
|
816
|
-
resource_type=ResourceType.PIPELINE_RUN,
|
817
|
-
list_method=zen_store().list_runs,
|
818
|
-
hydrate=hydrate,
|
819
|
-
)
|
820
|
-
|
821
|
-
|
822
|
-
@router.post(
|
823
|
-
WORKSPACES + "/{workspace_name_or_id}" + SCHEDULES,
|
824
|
-
response_model=ScheduleResponse,
|
825
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
826
|
-
)
|
827
|
-
@handle_exceptions
|
828
|
-
def create_schedule(
|
829
|
-
workspace_name_or_id: Union[str, UUID],
|
830
|
-
schedule: ScheduleRequest,
|
831
|
-
auth_context: AuthContext = Security(authorize),
|
832
|
-
) -> ScheduleResponse:
|
833
|
-
"""Creates a schedule.
|
834
|
-
|
835
|
-
Args:
|
836
|
-
workspace_name_or_id: Name or ID of the workspace.
|
837
|
-
schedule: Schedule to create.
|
838
|
-
auth_context: Authentication context.
|
839
|
-
|
840
|
-
Returns:
|
841
|
-
The created schedule.
|
842
|
-
|
843
|
-
Raises:
|
844
|
-
IllegalOperationError: If the workspace or user specified in the
|
845
|
-
schedule does not match the current workspace or authenticated user.
|
846
|
-
"""
|
847
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
848
|
-
|
849
|
-
if schedule.workspace != workspace.id:
|
850
|
-
raise IllegalOperationError(
|
851
|
-
"Creating pipeline runs outside of the workspace scope "
|
852
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
853
|
-
f"not supported."
|
854
|
-
)
|
855
|
-
if schedule.user != auth_context.user.id:
|
856
|
-
raise IllegalOperationError(
|
857
|
-
"Creating pipeline runs for a user other than yourself "
|
858
|
-
"is not supported."
|
859
|
-
)
|
860
|
-
return zen_store().create_schedule(schedule=schedule)
|
861
|
-
|
862
|
-
|
863
|
-
@router.post(
|
864
|
-
WORKSPACES + "/{workspace_name_or_id}" + RUNS,
|
865
|
-
response_model=PipelineRunResponse,
|
866
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
867
|
-
)
|
868
|
-
@handle_exceptions
|
869
|
-
def create_pipeline_run(
|
870
|
-
workspace_name_or_id: Union[str, UUID],
|
871
|
-
pipeline_run: PipelineRunRequest,
|
872
|
-
_: AuthContext = Security(authorize),
|
873
|
-
) -> PipelineRunResponse:
|
874
|
-
"""Creates a pipeline run.
|
875
|
-
|
876
|
-
Args:
|
877
|
-
workspace_name_or_id: Name or ID of the workspace.
|
878
|
-
pipeline_run: Pipeline run to create.
|
879
|
-
|
880
|
-
Returns:
|
881
|
-
The created pipeline run.
|
882
|
-
|
883
|
-
Raises:
|
884
|
-
IllegalOperationError: If the workspace specified in the
|
885
|
-
pipeline run does not match the current workspace.
|
886
|
-
"""
|
887
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
888
|
-
|
889
|
-
if pipeline_run.workspace != workspace.id:
|
890
|
-
raise IllegalOperationError(
|
891
|
-
"Creating pipeline runs outside of the workspace scope "
|
892
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
893
|
-
f"not supported."
|
894
|
-
)
|
895
|
-
|
896
|
-
return verify_permissions_and_create_entity(
|
897
|
-
request_model=pipeline_run,
|
898
|
-
resource_type=ResourceType.PIPELINE_RUN,
|
899
|
-
create_method=zen_store().create_run,
|
900
|
-
)
|
901
|
-
|
902
|
-
|
903
|
-
@router.post(
|
904
|
-
WORKSPACES + "/{workspace_name_or_id}" + RUNS + GET_OR_CREATE,
|
905
|
-
response_model=Tuple[PipelineRunResponse, bool],
|
906
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
907
|
-
)
|
908
|
-
@handle_exceptions
|
909
|
-
def get_or_create_pipeline_run(
|
910
|
-
workspace_name_or_id: Union[str, UUID],
|
911
|
-
pipeline_run: PipelineRunRequest,
|
912
|
-
auth_context: AuthContext = Security(authorize),
|
913
|
-
) -> Tuple[PipelineRunResponse, bool]:
|
914
|
-
"""Get or create a pipeline run.
|
915
|
-
|
916
|
-
Args:
|
917
|
-
workspace_name_or_id: Name or ID of the workspace.
|
918
|
-
pipeline_run: Pipeline run to create.
|
919
|
-
auth_context: Authentication context.
|
920
|
-
|
921
|
-
Returns:
|
922
|
-
The pipeline run and a boolean indicating whether the run was created
|
923
|
-
or not.
|
924
|
-
|
925
|
-
Raises:
|
926
|
-
IllegalOperationError: If the workspace or user specified in the
|
927
|
-
pipeline run does not match the current workspace or authenticated
|
928
|
-
user.
|
929
|
-
"""
|
930
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
931
|
-
if pipeline_run.workspace != workspace.id:
|
932
|
-
raise IllegalOperationError(
|
933
|
-
"Creating pipeline runs outside of the workspace scope "
|
934
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
935
|
-
f"not supported."
|
936
|
-
)
|
937
|
-
if pipeline_run.user != auth_context.user.id:
|
938
|
-
raise IllegalOperationError(
|
939
|
-
"Creating pipeline runs for a user other than yourself "
|
940
|
-
"is not supported."
|
941
|
-
)
|
942
|
-
|
943
|
-
def _pre_creation_hook() -> None:
|
944
|
-
verify_permission(
|
945
|
-
resource_type=ResourceType.PIPELINE_RUN, action=Action.CREATE
|
946
|
-
)
|
947
|
-
check_entitlement(resource_type=ResourceType.PIPELINE_RUN)
|
948
|
-
|
949
|
-
run, created = zen_store().get_or_create_run(
|
950
|
-
pipeline_run=pipeline_run, pre_creation_hook=_pre_creation_hook
|
951
|
-
)
|
952
|
-
if created:
|
953
|
-
report_usage(
|
954
|
-
resource_type=ResourceType.PIPELINE_RUN, resource_id=run.id
|
955
|
-
)
|
956
|
-
else:
|
957
|
-
verify_permission_for_model(run, action=Action.READ)
|
958
|
-
|
959
|
-
return run, created
|
960
|
-
|
961
|
-
|
962
|
-
@router.post(
|
963
|
-
WORKSPACES + "/{workspace_name_or_id}" + RUN_METADATA,
|
964
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
965
|
-
)
|
966
|
-
@handle_exceptions
|
967
|
-
def create_run_metadata(
|
968
|
-
workspace_name_or_id: Union[str, UUID],
|
969
|
-
run_metadata: RunMetadataRequest,
|
970
|
-
auth_context: AuthContext = Security(authorize),
|
971
|
-
) -> None:
|
972
|
-
"""Creates run metadata.
|
973
|
-
|
974
|
-
Args:
|
975
|
-
workspace_name_or_id: Name or ID of the workspace.
|
976
|
-
run_metadata: The run metadata to create.
|
977
|
-
auth_context: Authentication context.
|
978
|
-
|
979
|
-
Returns:
|
980
|
-
The created run metadata.
|
981
|
-
|
982
|
-
Raises:
|
983
|
-
IllegalOperationError: If the workspace or user specified in the run
|
984
|
-
metadata does not match the current workspace or authenticated user.
|
985
|
-
RuntimeError: If the resource type is not supported.
|
986
|
-
"""
|
987
|
-
workspace = zen_store().get_workspace(run_metadata.workspace)
|
988
|
-
|
989
|
-
if run_metadata.workspace != workspace.id:
|
990
|
-
raise IllegalOperationError(
|
991
|
-
"Creating run metadata outside of the workspace scope "
|
992
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
993
|
-
f"not supported."
|
994
|
-
)
|
995
|
-
|
996
|
-
if run_metadata.user != auth_context.user.id:
|
997
|
-
raise IllegalOperationError(
|
998
|
-
"Creating run metadata for a user other than yourself "
|
999
|
-
"is not supported."
|
1000
|
-
)
|
1001
|
-
|
1002
|
-
verify_models: List[Any] = []
|
1003
|
-
for resource in run_metadata.resources:
|
1004
|
-
if resource.type == MetadataResourceTypes.PIPELINE_RUN:
|
1005
|
-
verify_models.append(zen_store().get_run(resource.id))
|
1006
|
-
elif resource.type == MetadataResourceTypes.STEP_RUN:
|
1007
|
-
verify_models.append(zen_store().get_run_step(resource.id))
|
1008
|
-
elif resource.type == MetadataResourceTypes.ARTIFACT_VERSION:
|
1009
|
-
verify_models.append(zen_store().get_artifact_version(resource.id))
|
1010
|
-
elif resource.type == MetadataResourceTypes.MODEL_VERSION:
|
1011
|
-
verify_models.append(zen_store().get_model_version(resource.id))
|
1012
|
-
elif resource.type == MetadataResourceTypes.SCHEDULE:
|
1013
|
-
verify_models.append(zen_store().get_schedule(resource.id))
|
1014
|
-
else:
|
1015
|
-
raise RuntimeError(f"Unknown resource type: {resource.type}")
|
1016
|
-
|
1017
|
-
batch_verify_permissions_for_models(
|
1018
|
-
models=verify_models,
|
1019
|
-
action=Action.UPDATE,
|
1020
|
-
)
|
1021
|
-
|
1022
|
-
verify_permission(
|
1023
|
-
resource_type=ResourceType.RUN_METADATA, action=Action.CREATE
|
1024
|
-
)
|
1025
|
-
|
1026
|
-
zen_store().create_run_metadata(run_metadata)
|
1027
|
-
return None
|
1028
|
-
|
1029
|
-
|
1030
|
-
@router.post(
|
1031
|
-
WORKSPACES + "/{workspace_name_or_id}" + SECRETS,
|
1032
|
-
response_model=SecretResponse,
|
1033
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1034
|
-
)
|
1035
|
-
@handle_exceptions
|
1036
|
-
def create_secret(
|
1037
|
-
workspace_name_or_id: Union[str, UUID],
|
1038
|
-
secret: SecretRequest,
|
1039
|
-
_: AuthContext = Security(authorize),
|
1040
|
-
) -> SecretResponse:
|
1041
|
-
"""Creates a secret.
|
1042
|
-
|
1043
|
-
Args:
|
1044
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1045
|
-
secret: Secret to create.
|
1046
|
-
|
1047
|
-
Returns:
|
1048
|
-
The created secret.
|
1049
|
-
|
1050
|
-
Raises:
|
1051
|
-
IllegalOperationError: If the workspace specified in the
|
1052
|
-
secret does not match the current workspace.
|
1053
|
-
"""
|
1054
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1055
|
-
|
1056
|
-
if secret.workspace != workspace.id:
|
1057
|
-
raise IllegalOperationError(
|
1058
|
-
"Creating a secret outside of the workspace scope "
|
1059
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1060
|
-
f"not supported."
|
1061
|
-
)
|
1062
|
-
|
1063
|
-
return verify_permissions_and_create_entity(
|
1064
|
-
request_model=secret,
|
1065
|
-
resource_type=ResourceType.SECRET,
|
1066
|
-
create_method=zen_store().create_secret,
|
1067
|
-
)
|
1068
|
-
|
1069
|
-
|
1070
|
-
@router.get(
|
1071
|
-
WORKSPACES + "/{workspace_name_or_id}" + CODE_REPOSITORIES,
|
1072
|
-
response_model=Page[CodeRepositoryResponse],
|
1073
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
1074
|
-
)
|
1075
|
-
@handle_exceptions
|
1076
|
-
def list_workspace_code_repositories(
|
1077
|
-
workspace_name_or_id: Union[str, UUID],
|
1078
|
-
filter_model: CodeRepositoryFilter = Depends(
|
1079
|
-
make_dependable(CodeRepositoryFilter)
|
1080
|
-
),
|
1081
|
-
hydrate: bool = False,
|
1082
|
-
_: AuthContext = Security(authorize),
|
1083
|
-
) -> Page[CodeRepositoryResponse]:
|
1084
|
-
"""Gets code repositories defined for a specific workspace.
|
1085
|
-
|
1086
|
-
# noqa: DAR401
|
1087
|
-
|
1088
|
-
Args:
|
1089
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1090
|
-
filter_model: Filter model used for pagination, sorting,
|
1091
|
-
filtering.
|
1092
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
1093
|
-
by including metadata fields in the response.
|
1094
|
-
|
1095
|
-
Returns:
|
1096
|
-
All code repositories within the workspace.
|
1097
|
-
"""
|
1098
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1099
|
-
filter_model.set_scope_workspace(workspace.id)
|
1100
|
-
|
1101
|
-
return verify_permissions_and_list_entities(
|
1102
|
-
filter_model=filter_model,
|
1103
|
-
resource_type=ResourceType.CODE_REPOSITORY,
|
1104
|
-
list_method=zen_store().list_code_repositories,
|
1105
|
-
hydrate=hydrate,
|
1106
|
-
)
|
1107
|
-
|
1108
|
-
|
1109
|
-
@router.post(
|
1110
|
-
WORKSPACES + "/{workspace_name_or_id}" + CODE_REPOSITORIES,
|
1111
|
-
response_model=CodeRepositoryResponse,
|
1112
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1113
|
-
)
|
1114
|
-
@handle_exceptions
|
1115
|
-
def create_code_repository(
|
1116
|
-
workspace_name_or_id: Union[str, UUID],
|
1117
|
-
code_repository: CodeRepositoryRequest,
|
1118
|
-
_: AuthContext = Security(authorize),
|
1119
|
-
) -> CodeRepositoryResponse:
|
1120
|
-
"""Creates a code repository.
|
1121
|
-
|
1122
|
-
Args:
|
1123
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1124
|
-
code_repository: Code repository to create.
|
1125
|
-
|
1126
|
-
Returns:
|
1127
|
-
The created code repository.
|
1128
|
-
|
1129
|
-
Raises:
|
1130
|
-
IllegalOperationError: If the workspace or user specified in the
|
1131
|
-
code repository does not match the current workspace or
|
1132
|
-
authenticated user.
|
1133
|
-
"""
|
1134
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1135
|
-
|
1136
|
-
if code_repository.workspace != workspace.id:
|
1137
|
-
raise IllegalOperationError(
|
1138
|
-
"Creating code repositories outside of the workspace scope "
|
1139
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1140
|
-
f"not supported."
|
1141
|
-
)
|
1142
|
-
|
1143
|
-
return verify_permissions_and_create_entity(
|
1144
|
-
request_model=code_repository,
|
1145
|
-
resource_type=ResourceType.CODE_REPOSITORY,
|
1146
|
-
create_method=zen_store().create_code_repository,
|
1147
|
-
)
|
1148
|
-
|
1149
|
-
|
1150
|
-
@router.get(
|
1151
|
-
WORKSPACES + "/{workspace_name_or_id}" + STATISTICS,
|
1152
|
-
response_model=Dict[str, int],
|
1153
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
1154
|
-
)
|
1155
|
-
@handle_exceptions
|
1156
|
-
def get_workspace_statistics(
|
1157
|
-
workspace_name_or_id: Union[str, UUID],
|
1158
|
-
auth_context: AuthContext = Security(authorize),
|
1159
|
-
) -> Dict[str, int]:
|
1160
|
-
"""Gets statistics of a workspace.
|
1161
|
-
|
1162
|
-
# noqa: DAR401
|
1163
|
-
|
1164
|
-
Args:
|
1165
|
-
workspace_name_or_id: Name or ID of the workspace to get statistics for.
|
1166
|
-
auth_context: Authentication context.
|
1167
|
-
|
1168
|
-
Returns:
|
1169
|
-
All pipelines within the workspace.
|
1170
|
-
"""
|
1171
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1172
|
-
|
1173
|
-
user_id = auth_context.user.id
|
1174
|
-
component_filter = ComponentFilter(workspace_id=workspace.id)
|
1175
|
-
component_filter.configure_rbac(
|
1176
|
-
authenticated_user_id=user_id,
|
1177
|
-
id=get_allowed_resource_ids(
|
1178
|
-
resource_type=ResourceType.STACK_COMPONENT
|
1179
|
-
),
|
1180
|
-
)
|
1181
|
-
|
1182
|
-
stack_filter = StackFilter(workspace_id=workspace.id)
|
1183
|
-
stack_filter.configure_rbac(
|
1184
|
-
authenticated_user_id=user_id,
|
1185
|
-
id=get_allowed_resource_ids(resource_type=ResourceType.STACK),
|
1186
|
-
)
|
1187
|
-
|
1188
|
-
run_filter = PipelineRunFilter(workspace_id=workspace.id)
|
1189
|
-
run_filter.configure_rbac(
|
1190
|
-
authenticated_user_id=user_id,
|
1191
|
-
id=get_allowed_resource_ids(resource_type=ResourceType.PIPELINE_RUN),
|
1192
|
-
)
|
1193
|
-
|
1194
|
-
pipeline_filter = PipelineFilter(workspace_id=workspace.id)
|
1195
|
-
pipeline_filter.configure_rbac(
|
1196
|
-
authenticated_user_id=user_id,
|
1197
|
-
id=get_allowed_resource_ids(resource_type=ResourceType.PIPELINE),
|
1198
|
-
)
|
1199
|
-
|
1200
|
-
return {
|
1201
|
-
"stacks": zen_store().count_stacks(filter_model=stack_filter),
|
1202
|
-
"components": zen_store().count_stack_components(
|
1203
|
-
filter_model=component_filter
|
1204
|
-
),
|
1205
|
-
"pipelines": zen_store().count_pipelines(filter_model=pipeline_filter),
|
1206
|
-
"runs": zen_store().count_runs(filter_model=run_filter),
|
1207
|
-
}
|
1208
|
-
|
1209
|
-
|
1210
|
-
@router.get(
|
1211
|
-
WORKSPACES + "/{workspace_name_or_id}" + SERVICE_CONNECTORS,
|
1212
|
-
response_model=Page[ServiceConnectorResponse],
|
1213
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
1214
|
-
)
|
1215
|
-
@handle_exceptions
|
1216
|
-
def list_workspace_service_connectors(
|
1217
|
-
workspace_name_or_id: Union[str, UUID],
|
1218
|
-
connector_filter_model: ServiceConnectorFilter = Depends(
|
1219
|
-
make_dependable(ServiceConnectorFilter)
|
1220
|
-
),
|
1221
|
-
hydrate: bool = False,
|
1222
|
-
_: AuthContext = Security(authorize),
|
1223
|
-
) -> Page[ServiceConnectorResponse]:
|
1224
|
-
"""List service connectors that are part of a specific workspace.
|
1225
|
-
|
1226
|
-
# noqa: DAR401
|
1227
|
-
|
1228
|
-
Args:
|
1229
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1230
|
-
connector_filter_model: Filter model used for pagination, sorting,
|
1231
|
-
filtering.
|
1232
|
-
hydrate: Flag deciding whether to hydrate the output model(s)
|
1233
|
-
by including metadata fields in the response.
|
1234
|
-
|
1235
|
-
Returns:
|
1236
|
-
All service connectors part of the specified workspace.
|
1237
|
-
"""
|
1238
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1239
|
-
connector_filter_model.set_scope_workspace(workspace.id)
|
1240
|
-
|
1241
|
-
return verify_permissions_and_list_entities(
|
1242
|
-
filter_model=connector_filter_model,
|
1243
|
-
resource_type=ResourceType.SERVICE_CONNECTOR,
|
1244
|
-
list_method=zen_store().list_service_connectors,
|
1245
|
-
hydrate=hydrate,
|
1246
|
-
)
|
1247
|
-
|
1248
|
-
|
1249
|
-
@router.post(
|
1250
|
-
WORKSPACES + "/{workspace_name_or_id}" + SERVICE_CONNECTORS,
|
1251
|
-
response_model=ServiceConnectorResponse,
|
1252
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1253
|
-
)
|
1254
|
-
@handle_exceptions
|
1255
|
-
def create_service_connector(
|
1256
|
-
workspace_name_or_id: Union[str, UUID],
|
1257
|
-
connector: ServiceConnectorRequest,
|
1258
|
-
_: AuthContext = Security(authorize),
|
1259
|
-
) -> ServiceConnectorResponse:
|
1260
|
-
"""Creates a service connector.
|
1261
|
-
|
1262
|
-
Args:
|
1263
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1264
|
-
connector: Service connector to register.
|
1265
|
-
|
1266
|
-
Returns:
|
1267
|
-
The created service connector.
|
1268
|
-
|
1269
|
-
Raises:
|
1270
|
-
IllegalOperationError: If the workspace or user specified in the service
|
1271
|
-
connector does not match the current workspace or authenticated
|
1272
|
-
user.
|
1273
|
-
"""
|
1274
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1275
|
-
|
1276
|
-
if connector.workspace != workspace.id:
|
1277
|
-
raise IllegalOperationError(
|
1278
|
-
"Creating connectors outside of the workspace scope "
|
1279
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1280
|
-
f"not supported."
|
1281
|
-
)
|
1282
|
-
|
1283
|
-
return verify_permissions_and_create_entity(
|
1284
|
-
request_model=connector,
|
1285
|
-
resource_type=ResourceType.SERVICE_CONNECTOR,
|
1286
|
-
create_method=zen_store().create_service_connector,
|
1287
|
-
)
|
1288
|
-
|
1289
|
-
|
1290
|
-
@router.get(
|
1291
|
-
WORKSPACES
|
1292
|
-
+ "/{workspace_name_or_id}"
|
1293
|
-
+ SERVICE_CONNECTORS
|
1294
|
-
+ SERVICE_CONNECTOR_RESOURCES,
|
1295
|
-
response_model=List[ServiceConnectorResourcesModel],
|
1296
|
-
responses={401: error_response, 404: error_response, 422: error_response},
|
1297
|
-
)
|
1298
|
-
@handle_exceptions
|
1299
|
-
def list_service_connector_resources(
|
1300
|
-
workspace_name_or_id: Union[str, UUID],
|
1301
|
-
connector_type: Optional[str] = None,
|
1302
|
-
resource_type: Optional[str] = None,
|
1303
|
-
resource_id: Optional[str] = None,
|
1304
|
-
auth_context: AuthContext = Security(authorize),
|
1305
|
-
) -> List[ServiceConnectorResourcesModel]:
|
1306
|
-
"""List resources that can be accessed by service connectors.
|
1307
|
-
|
1308
|
-
Args:
|
1309
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1310
|
-
connector_type: the service connector type identifier to filter by.
|
1311
|
-
resource_type: the resource type identifier to filter by.
|
1312
|
-
resource_id: the resource identifier to filter by.
|
1313
|
-
auth_context: Authentication context.
|
1314
|
-
|
1315
|
-
Returns:
|
1316
|
-
The matching list of resources that available service
|
1317
|
-
connectors have access to.
|
1318
|
-
"""
|
1319
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1320
|
-
|
1321
|
-
filter_model = ServiceConnectorFilter(
|
1322
|
-
connector_type=connector_type,
|
1323
|
-
resource_type=resource_type,
|
1324
|
-
)
|
1325
|
-
filter_model.set_scope_workspace(workspace.id)
|
1326
|
-
|
1327
|
-
allowed_ids = get_allowed_resource_ids(
|
1328
|
-
resource_type=ResourceType.SERVICE_CONNECTOR
|
1329
|
-
)
|
1330
|
-
filter_model.configure_rbac(
|
1331
|
-
authenticated_user_id=auth_context.user.id, id=allowed_ids
|
1332
|
-
)
|
1333
|
-
|
1334
|
-
return zen_store().list_service_connector_resources(
|
1335
|
-
workspace_name_or_id=workspace_name_or_id,
|
1336
|
-
connector_type=connector_type,
|
1337
|
-
resource_type=resource_type,
|
1338
|
-
resource_id=resource_id,
|
1339
|
-
filter_model=filter_model,
|
1340
|
-
)
|
1341
|
-
|
1342
|
-
|
1343
|
-
@router.post(
|
1344
|
-
WORKSPACES + "/{workspace_name_or_id}" + MODELS,
|
1345
|
-
response_model=ModelResponse,
|
1346
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1347
|
-
)
|
1348
|
-
@handle_exceptions
|
1349
|
-
def create_model(
|
1350
|
-
workspace_name_or_id: Union[str, UUID],
|
1351
|
-
model: ModelRequest,
|
1352
|
-
_: AuthContext = Security(authorize),
|
1353
|
-
) -> ModelResponse:
|
1354
|
-
"""Create a new model.
|
1355
|
-
|
1356
|
-
Args:
|
1357
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1358
|
-
model: The model to create.
|
1359
|
-
|
1360
|
-
Returns:
|
1361
|
-
The created model.
|
1362
|
-
|
1363
|
-
Raises:
|
1364
|
-
IllegalOperationError: If the workspace or user specified in the
|
1365
|
-
model does not match the current workspace or authenticated
|
1366
|
-
user.
|
1367
|
-
"""
|
1368
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1369
|
-
|
1370
|
-
if model.workspace != workspace.id:
|
1371
|
-
raise IllegalOperationError(
|
1372
|
-
"Creating models outside of the workspace scope "
|
1373
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1374
|
-
f"not supported."
|
1375
|
-
)
|
1376
|
-
|
1377
|
-
return verify_permissions_and_create_entity(
|
1378
|
-
request_model=model,
|
1379
|
-
resource_type=ResourceType.MODEL,
|
1380
|
-
create_method=zen_store().create_model,
|
1381
|
-
)
|
1382
|
-
|
1383
|
-
|
1384
|
-
@router.post(
|
1385
|
-
WORKSPACES
|
1386
|
-
+ "/{workspace_name_or_id}"
|
1387
|
-
+ MODELS
|
1388
|
-
+ "/{model_name_or_id}"
|
1389
|
-
+ MODEL_VERSIONS,
|
1390
|
-
response_model=ModelVersionResponse,
|
1391
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1392
|
-
)
|
1393
|
-
@handle_exceptions
|
1394
|
-
def create_model_version(
|
1395
|
-
workspace_name_or_id: Union[str, UUID],
|
1396
|
-
model_name_or_id: Union[str, UUID],
|
1397
|
-
model_version: ModelVersionRequest,
|
1398
|
-
auth_context: AuthContext = Security(authorize),
|
1399
|
-
) -> ModelVersionResponse:
|
1400
|
-
"""Create a new model version.
|
1401
|
-
|
1402
|
-
Args:
|
1403
|
-
model_name_or_id: Name or ID of the model.
|
1404
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1405
|
-
model_version: The model version to create.
|
1406
|
-
auth_context: Authentication context.
|
1407
|
-
|
1408
|
-
Returns:
|
1409
|
-
The created model version.
|
1410
|
-
|
1411
|
-
Raises:
|
1412
|
-
IllegalOperationError: If the workspace specified in the
|
1413
|
-
model version does not match the current workspace.
|
1414
|
-
"""
|
1415
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1416
|
-
|
1417
|
-
if model_version.workspace != workspace.id:
|
1418
|
-
raise IllegalOperationError(
|
1419
|
-
"Creating model versions outside of the workspace scope "
|
1420
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1421
|
-
f"not supported."
|
1422
|
-
)
|
1423
|
-
|
1424
|
-
return verify_permissions_and_create_entity(
|
1425
|
-
request_model=model_version,
|
1426
|
-
resource_type=ResourceType.MODEL_VERSION,
|
1427
|
-
create_method=zen_store().create_model_version,
|
1428
|
-
)
|
1429
|
-
|
1430
|
-
|
1431
|
-
@router.post(
|
1432
|
-
WORKSPACES + "/{workspace_name_or_id}" + SERVICES,
|
1433
|
-
response_model=ServiceResponse,
|
1434
|
-
responses={401: error_response, 409: error_response, 422: error_response},
|
1435
|
-
)
|
1436
|
-
@handle_exceptions
|
1437
|
-
def create_service(
|
1438
|
-
workspace_name_or_id: Union[str, UUID],
|
1439
|
-
service: ServiceRequest,
|
1440
|
-
_: AuthContext = Security(authorize),
|
1441
|
-
) -> ServiceResponse:
|
1442
|
-
"""Create a new service.
|
1443
|
-
|
1444
|
-
Args:
|
1445
|
-
workspace_name_or_id: Name or ID of the workspace.
|
1446
|
-
service: The service to create.
|
1447
|
-
|
1448
|
-
Returns:
|
1449
|
-
The created service.
|
1450
|
-
|
1451
|
-
Raises:
|
1452
|
-
IllegalOperationError: If the workspace or user specified in the
|
1453
|
-
model does not match the current workspace or authenticated
|
1454
|
-
user.
|
1455
|
-
"""
|
1456
|
-
workspace = zen_store().get_workspace(workspace_name_or_id)
|
1457
|
-
|
1458
|
-
if service.workspace != workspace.id:
|
1459
|
-
raise IllegalOperationError(
|
1460
|
-
"Creating models outside of the workspace scope "
|
1461
|
-
f"of this endpoint `{workspace_name_or_id}` is "
|
1462
|
-
f"not supported."
|
1463
|
-
)
|
1464
|
-
|
1465
|
-
return verify_permissions_and_create_entity(
|
1466
|
-
request_model=service,
|
1467
|
-
resource_type=ResourceType.SERVICE,
|
1468
|
-
create_method=zen_store().create_service,
|
237
|
+
return WorkspaceStatistics(
|
238
|
+
pipelines=zen_store().count_pipelines(filter_model=pipeline_filter),
|
239
|
+
runs=zen_store().count_runs(filter_model=run_filter),
|
1469
240
|
)
|