zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250314__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zenml/VERSION +1 -1
- zenml/__init__.py +2 -0
- zenml/analytics/context.py +7 -0
- zenml/analytics/enums.py +2 -2
- zenml/artifacts/utils.py +2 -4
- zenml/cli/__init__.py +8 -9
- zenml/cli/base.py +2 -2
- zenml/cli/code_repository.py +1 -1
- zenml/cli/login.py +6 -0
- zenml/cli/model.py +7 -15
- zenml/cli/pipeline.py +3 -3
- zenml/cli/project.py +172 -0
- zenml/cli/secret.py +47 -44
- zenml/cli/service_accounts.py +0 -1
- zenml/cli/service_connectors.py +15 -17
- zenml/cli/stack.py +0 -3
- zenml/cli/stack_components.py +2 -2
- zenml/cli/tag.py +3 -5
- zenml/cli/utils.py +25 -23
- zenml/client.py +749 -475
- zenml/config/global_config.py +48 -37
- zenml/config/pipeline_configurations.py +3 -2
- zenml/config/pipeline_run_configuration.py +2 -1
- zenml/config/secret_reference_mixin.py +1 -1
- zenml/constants.py +6 -6
- zenml/enums.py +0 -7
- zenml/event_hub/event_hub.py +3 -1
- zenml/exceptions.py +0 -24
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +7 -6
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
- zenml/integrations/mlflow/steps/mlflow_registry.py +3 -3
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
- zenml/integrations/wandb/__init__.py +1 -1
- zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py +29 -9
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +5 -3
- zenml/model/model.py +10 -10
- zenml/model_registries/base_model_registry.py +1 -1
- zenml/models/__init__.py +45 -28
- zenml/models/v2/base/base.py +0 -5
- zenml/models/v2/base/filter.py +2 -2
- zenml/models/v2/base/scoped.py +135 -156
- zenml/models/v2/core/action.py +12 -12
- zenml/models/v2/core/api_key.py +1 -1
- zenml/models/v2/core/artifact.py +31 -18
- zenml/models/v2/core/artifact_version.py +57 -40
- zenml/models/v2/core/code_repository.py +12 -12
- zenml/models/v2/core/component.py +22 -33
- zenml/models/v2/core/device.py +3 -2
- zenml/models/v2/core/event_source.py +14 -14
- zenml/models/v2/core/flavor.py +19 -47
- zenml/models/v2/core/logs.py +1 -2
- zenml/models/v2/core/model.py +23 -20
- zenml/models/v2/core/model_version.py +51 -42
- zenml/models/v2/core/pipeline.py +16 -16
- zenml/models/v2/core/pipeline_build.py +14 -14
- zenml/models/v2/core/pipeline_deployment.py +12 -14
- zenml/models/v2/core/pipeline_run.py +21 -29
- zenml/models/v2/core/project.py +203 -0
- zenml/models/v2/core/run_metadata.py +2 -2
- zenml/models/v2/core/run_template.py +16 -17
- zenml/models/v2/core/schedule.py +12 -21
- zenml/models/v2/core/secret.py +94 -128
- zenml/models/v2/core/server_settings.py +2 -2
- zenml/models/v2/core/service.py +57 -26
- zenml/models/v2/core/service_connector.py +14 -16
- zenml/models/v2/core/stack.py +24 -26
- zenml/models/v2/core/step_run.py +16 -28
- zenml/models/v2/core/tag.py +41 -15
- zenml/models/v2/core/trigger.py +13 -13
- zenml/models/v2/core/trigger_execution.py +2 -2
- zenml/models/v2/core/user.py +2 -2
- zenml/models/v2/misc/statistics.py +45 -0
- zenml/models/v2/misc/tag.py +27 -0
- zenml/orchestrators/cache_utils.py +7 -7
- zenml/orchestrators/input_utils.py +1 -0
- zenml/orchestrators/step_launcher.py +1 -2
- zenml/orchestrators/step_run_utils.py +2 -4
- zenml/orchestrators/step_runner.py +10 -1
- zenml/orchestrators/utils.py +4 -4
- zenml/pipelines/build_utils.py +2 -4
- zenml/pipelines/pipeline_decorator.py +3 -2
- zenml/pipelines/pipeline_definition.py +8 -9
- zenml/pipelines/run_utils.py +4 -4
- zenml/service_connectors/service_connector.py +0 -10
- zenml/service_connectors/service_connector_utils.py +0 -2
- zenml/stack/authentication_mixin.py +1 -1
- zenml/stack/flavor.py +3 -14
- zenml/stack/stack.py +0 -1
- zenml/stack/stack_component.py +1 -5
- zenml/steps/base_step.py +10 -2
- zenml/steps/step_context.py +19 -0
- zenml/utils/string_utils.py +1 -1
- zenml/utils/tag_utils.py +642 -0
- zenml/zen_server/cloud_utils.py +21 -0
- zenml/zen_server/exceptions.py +0 -6
- zenml/zen_server/rbac/endpoint_utils.py +134 -46
- zenml/zen_server/rbac/models.py +65 -3
- zenml/zen_server/rbac/rbac_interface.py +9 -0
- zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
- zenml/zen_server/rbac/utils.py +155 -30
- zenml/zen_server/rbac/zenml_cloud_rbac.py +39 -11
- zenml/zen_server/routers/actions_endpoints.py +3 -5
- zenml/zen_server/routers/artifact_endpoint.py +0 -5
- zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
- zenml/zen_server/routers/auth_endpoints.py +22 -7
- zenml/zen_server/routers/code_repositories_endpoints.py +54 -3
- zenml/zen_server/routers/devices_endpoints.py +0 -4
- zenml/zen_server/routers/event_source_endpoints.py +0 -5
- zenml/zen_server/routers/flavors_endpoints.py +0 -5
- zenml/zen_server/routers/logs_endpoints.py +0 -1
- zenml/zen_server/routers/model_versions_endpoints.py +100 -23
- zenml/zen_server/routers/models_endpoints.py +50 -69
- zenml/zen_server/routers/pipeline_builds_endpoints.py +55 -3
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +56 -4
- zenml/zen_server/routers/pipelines_endpoints.py +70 -3
- zenml/zen_server/routers/plugin_endpoints.py +0 -1
- zenml/zen_server/routers/projects_endpoints.py +283 -0
- zenml/zen_server/routers/run_metadata_endpoints.py +97 -0
- zenml/zen_server/routers/run_templates_endpoints.py +64 -3
- zenml/zen_server/routers/runs_endpoints.py +58 -8
- zenml/zen_server/routers/schedule_endpoints.py +67 -6
- zenml/zen_server/routers/secrets_endpoints.py +38 -4
- zenml/zen_server/routers/server_endpoints.py +53 -1
- zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
- zenml/zen_server/routers/service_connectors_endpoints.py +94 -14
- zenml/zen_server/routers/service_endpoints.py +18 -7
- zenml/zen_server/routers/stack_components_endpoints.py +66 -7
- zenml/zen_server/routers/stacks_endpoints.py +95 -6
- zenml/zen_server/routers/steps_endpoints.py +17 -11
- zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
- zenml/zen_server/routers/tags_endpoints.py +6 -17
- zenml/zen_server/routers/triggers_endpoints.py +5 -8
- zenml/zen_server/routers/users_endpoints.py +9 -12
- zenml/zen_server/template_execution/utils.py +8 -7
- zenml/zen_server/utils.py +21 -0
- zenml/zen_server/zen_server_api.py +7 -2
- zenml/zen_stores/base_zen_store.py +50 -69
- zenml/zen_stores/migrations/versions/12eff0206201_rename_workspace_to_project.py +768 -0
- zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
- zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
- zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
- zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
- zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
- zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
- zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
- zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
- zenml/zen_stores/migrations/versions/cbc6acd71f92_add_workspace_display_name.py +58 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
- zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
- zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
- zenml/zen_stores/rest_zen_store.py +223 -230
- zenml/zen_stores/schemas/__init__.py +2 -2
- zenml/zen_stores/schemas/action_schemas.py +15 -8
- zenml/zen_stores/schemas/api_key_schemas.py +8 -1
- zenml/zen_stores/schemas/artifact_schemas.py +35 -10
- zenml/zen_stores/schemas/code_repository_schemas.py +22 -17
- zenml/zen_stores/schemas/component_schemas.py +9 -14
- zenml/zen_stores/schemas/event_source_schemas.py +15 -8
- zenml/zen_stores/schemas/flavor_schemas.py +14 -20
- zenml/zen_stores/schemas/model_schemas.py +18 -17
- zenml/zen_stores/schemas/pipeline_build_schemas.py +7 -7
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +10 -8
- zenml/zen_stores/schemas/pipeline_run_schemas.py +9 -12
- zenml/zen_stores/schemas/pipeline_schemas.py +9 -9
- zenml/zen_stores/schemas/{workspace_schemas.py → project_schemas.py} +53 -65
- zenml/zen_stores/schemas/run_metadata_schemas.py +5 -5
- zenml/zen_stores/schemas/run_template_schemas.py +17 -13
- zenml/zen_stores/schemas/schedule_schema.py +16 -21
- zenml/zen_stores/schemas/secret_schemas.py +15 -25
- zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
- zenml/zen_stores/schemas/service_schemas.py +7 -8
- zenml/zen_stores/schemas/stack_schemas.py +12 -15
- zenml/zen_stores/schemas/step_run_schemas.py +14 -15
- zenml/zen_stores/schemas/tag_schemas.py +30 -2
- zenml/zen_stores/schemas/trigger_schemas.py +15 -8
- zenml/zen_stores/schemas/user_schemas.py +12 -2
- zenml/zen_stores/schemas/utils.py +16 -0
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
- zenml/zen_stores/sql_zen_store.py +2984 -2369
- zenml/zen_stores/template_utils.py +1 -1
- zenml/zen_stores/zen_store_interface.py +136 -126
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/METADATA +1 -1
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/RECORD +188 -173
- zenml/cli/workspace.py +0 -86
- zenml/models/v2/core/workspace.py +0 -131
- zenml/zen_server/routers/workspaces_endpoints.py +0 -1469
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/entry_points.txt +0 -0
@@ -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,16 @@ 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.projects_endpoints import workspace_router
|
29
35
|
from zenml.zen_server.utils import (
|
30
36
|
handle_exceptions,
|
31
37
|
make_dependable,
|
@@ -39,16 +45,64 @@ router = APIRouter(
|
|
39
45
|
)
|
40
46
|
|
41
47
|
|
48
|
+
@router.post(
|
49
|
+
"",
|
50
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
51
|
+
)
|
52
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
53
|
+
# and can be removed after the migration
|
54
|
+
@workspace_router.post(
|
55
|
+
"/{project_name_or_id}" + SCHEDULES,
|
56
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
57
|
+
deprecated=True,
|
58
|
+
tags=["schedules"],
|
59
|
+
)
|
60
|
+
@handle_exceptions
|
61
|
+
def create_schedule(
|
62
|
+
schedule: ScheduleRequest,
|
63
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
64
|
+
auth_context: AuthContext = Security(authorize),
|
65
|
+
) -> ScheduleResponse:
|
66
|
+
"""Creates a schedule.
|
67
|
+
|
68
|
+
Args:
|
69
|
+
schedule: Schedule to create.
|
70
|
+
project_name_or_id: Optional name or ID of the project.
|
71
|
+
auth_context: Authentication context.
|
72
|
+
|
73
|
+
Returns:
|
74
|
+
The created schedule.
|
75
|
+
"""
|
76
|
+
if project_name_or_id:
|
77
|
+
project = zen_store().get_project(project_name_or_id)
|
78
|
+
schedule.project = project.id
|
79
|
+
|
80
|
+
# NOTE: no RBAC is enforced currently for schedules, but we're
|
81
|
+
# keeping the RBAC checks here for consistency
|
82
|
+
return verify_permissions_and_create_entity(
|
83
|
+
request_model=schedule,
|
84
|
+
create_method=zen_store().create_schedule,
|
85
|
+
)
|
86
|
+
|
87
|
+
|
42
88
|
@router.get(
|
43
89
|
"",
|
44
|
-
response_model=Page[ScheduleResponse],
|
45
90
|
responses={401: error_response, 404: error_response, 422: error_response},
|
46
91
|
)
|
92
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
93
|
+
# and can be removed after the migration
|
94
|
+
@workspace_router.get(
|
95
|
+
"/{project_name_or_id}" + SCHEDULES,
|
96
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
97
|
+
deprecated=True,
|
98
|
+
tags=["schedules"],
|
99
|
+
)
|
47
100
|
@handle_exceptions
|
48
101
|
def list_schedules(
|
49
102
|
schedule_filter_model: ScheduleFilter = Depends(
|
50
103
|
make_dependable(ScheduleFilter)
|
51
104
|
),
|
105
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
52
106
|
hydrate: bool = False,
|
53
107
|
_: AuthContext = Security(authorize),
|
54
108
|
) -> Page[ScheduleResponse]:
|
@@ -57,20 +111,24 @@ def list_schedules(
|
|
57
111
|
Args:
|
58
112
|
schedule_filter_model: Filter model used for pagination, sorting,
|
59
113
|
filtering
|
114
|
+
project_name_or_id: Optional name or ID of the project.
|
60
115
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
61
116
|
by including metadata fields in the response.
|
62
117
|
|
63
118
|
Returns:
|
64
119
|
List of schedule objects.
|
65
120
|
"""
|
121
|
+
if project_name_or_id:
|
122
|
+
schedule_filter_model.project = project_name_or_id
|
123
|
+
|
66
124
|
return zen_store().list_schedules(
|
67
|
-
schedule_filter_model=schedule_filter_model,
|
125
|
+
schedule_filter_model=schedule_filter_model,
|
126
|
+
hydrate=hydrate,
|
68
127
|
)
|
69
128
|
|
70
129
|
|
71
130
|
@router.get(
|
72
131
|
"/{schedule_id}",
|
73
|
-
response_model=ScheduleResponse,
|
74
132
|
responses={401: error_response, 404: error_response, 422: error_response},
|
75
133
|
)
|
76
134
|
@handle_exceptions
|
@@ -89,12 +147,14 @@ def get_schedule(
|
|
89
147
|
Returns:
|
90
148
|
A specific schedule object.
|
91
149
|
"""
|
92
|
-
return zen_store().get_schedule(
|
150
|
+
return zen_store().get_schedule(
|
151
|
+
schedule_id=schedule_id,
|
152
|
+
hydrate=hydrate,
|
153
|
+
)
|
93
154
|
|
94
155
|
|
95
156
|
@router.put(
|
96
157
|
"/{schedule_id}",
|
97
|
-
response_model=ScheduleResponse,
|
98
158
|
responses={401: error_response, 404: error_response, 422: error_response},
|
99
159
|
)
|
100
160
|
@handle_exceptions
|
@@ -113,7 +173,8 @@ def update_schedule(
|
|
113
173
|
The updated schedule object.
|
114
174
|
"""
|
115
175
|
return zen_store().update_schedule(
|
116
|
-
schedule_id=schedule_id,
|
176
|
+
schedule_id=schedule_id,
|
177
|
+
schedule_update=schedule_update,
|
117
178
|
)
|
118
179
|
|
119
180
|
|
@@ -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,7 @@ 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.projects_endpoints import workspace_router
|
50
53
|
from zenml.zen_server.utils import (
|
51
54
|
handle_exceptions,
|
52
55
|
make_dependable,
|
@@ -66,9 +69,41 @@ op_router = APIRouter(
|
|
66
69
|
)
|
67
70
|
|
68
71
|
|
72
|
+
@router.post(
|
73
|
+
"",
|
74
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
75
|
+
)
|
76
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
77
|
+
# and can be removed after the migration
|
78
|
+
@workspace_router.post(
|
79
|
+
"/{workspace_name_or_id}" + SECRETS,
|
80
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
81
|
+
deprecated=True,
|
82
|
+
tags=["secrets"],
|
83
|
+
)
|
84
|
+
@handle_exceptions
|
85
|
+
def create_secret(
|
86
|
+
secret: SecretRequest,
|
87
|
+
workspace_name_or_id: Optional[Union[str, UUID]] = None,
|
88
|
+
_: AuthContext = Security(authorize),
|
89
|
+
) -> SecretResponse:
|
90
|
+
"""Creates a secret.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
secret: Secret to create.
|
94
|
+
workspace_name_or_id: Optional name or ID of the workspace.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
The created secret.
|
98
|
+
"""
|
99
|
+
return verify_permissions_and_create_entity(
|
100
|
+
request_model=secret,
|
101
|
+
create_method=zen_store().create_secret,
|
102
|
+
)
|
103
|
+
|
104
|
+
|
69
105
|
@router.get(
|
70
106
|
"",
|
71
|
-
response_model=Page[SecretResponse],
|
72
107
|
responses={401: error_response, 404: error_response, 422: error_response},
|
73
108
|
)
|
74
109
|
@handle_exceptions
|
@@ -116,7 +151,6 @@ def list_secrets(
|
|
116
151
|
|
117
152
|
@router.get(
|
118
153
|
"/{secret_id}",
|
119
|
-
response_model=SecretResponse,
|
120
154
|
responses={401: error_response, 404: error_response, 422: error_response},
|
121
155
|
)
|
122
156
|
@handle_exceptions
|
@@ -140,6 +174,7 @@ def get_secret(
|
|
140
174
|
get_method=zen_store().get_secret,
|
141
175
|
hydrate=hydrate,
|
142
176
|
)
|
177
|
+
|
143
178
|
if not has_permissions_for_model(secret, action=Action.READ_SECRET_VALUE):
|
144
179
|
secret.remove_secrets()
|
145
180
|
|
@@ -148,7 +183,6 @@ def get_secret(
|
|
148
183
|
|
149
184
|
@router.put(
|
150
185
|
"/{secret_id}",
|
151
|
-
response_model=SecretResponse,
|
152
186
|
responses={401: error_response, 404: error_response, 422: error_response},
|
153
187
|
)
|
154
188
|
@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,
|
35
|
+
ProjectFilter,
|
33
36
|
ServerActivationRequest,
|
34
37
|
ServerLoadInfo,
|
35
38
|
ServerModel,
|
36
39
|
ServerSettingsResponse,
|
37
40
|
ServerSettingsUpdate,
|
41
|
+
ServerStatistics,
|
42
|
+
StackFilter,
|
38
43
|
UserResponse,
|
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
|
+
project_filter = ProjectFilter()
|
271
|
+
project_filter.configure_rbac(
|
272
|
+
authenticated_user_id=user_id,
|
273
|
+
id=get_allowed_resource_ids(resource_type=ResourceType.PROJECT),
|
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
|
+
projects=zen_store().count_projects(filter_model=project_filter),
|
288
|
+
)
|
@@ -67,7 +67,6 @@ router = APIRouter(
|
|
67
67
|
|
68
68
|
@router.post(
|
69
69
|
"",
|
70
|
-
response_model=ServiceAccountResponse,
|
71
70
|
responses={
|
72
71
|
401: error_response,
|
73
72
|
409: error_response,
|
@@ -89,14 +88,12 @@ def create_service_account(
|
|
89
88
|
"""
|
90
89
|
return verify_permissions_and_create_entity(
|
91
90
|
request_model=service_account,
|
92
|
-
resource_type=ResourceType.SERVICE_ACCOUNT,
|
93
91
|
create_method=zen_store().create_service_account,
|
94
92
|
)
|
95
93
|
|
96
94
|
|
97
95
|
@router.get(
|
98
96
|
"/{service_account_name_or_id}",
|
99
|
-
response_model=ServiceAccountResponse,
|
100
97
|
responses={401: error_response, 404: error_response, 422: error_response},
|
101
98
|
)
|
102
99
|
@handle_exceptions
|
@@ -124,7 +121,6 @@ def get_service_account(
|
|
124
121
|
|
125
122
|
@router.get(
|
126
123
|
"",
|
127
|
-
response_model=Page[ServiceAccountResponse],
|
128
124
|
responses={401: error_response, 404: error_response, 422: error_response},
|
129
125
|
)
|
130
126
|
@handle_exceptions
|
@@ -156,7 +152,6 @@ def list_service_accounts(
|
|
156
152
|
|
157
153
|
@router.put(
|
158
154
|
"/{service_account_name_or_id}",
|
159
|
-
response_model=ServiceAccountResponse,
|
160
155
|
responses={
|
161
156
|
401: error_response,
|
162
157
|
404: error_response,
|
@@ -214,7 +209,6 @@ def delete_service_account(
|
|
214
209
|
|
215
210
|
@router.post(
|
216
211
|
"/{service_account_id}" + API_KEYS,
|
217
|
-
response_model=APIKeyResponse,
|
218
212
|
responses={401: error_response, 409: error_response, 422: error_response},
|
219
213
|
)
|
220
214
|
@handle_exceptions
|
@@ -233,18 +227,26 @@ def create_api_key(
|
|
233
227
|
Returns:
|
234
228
|
The created API key.
|
235
229
|
"""
|
230
|
+
|
231
|
+
def create_api_key_wrapper(
|
232
|
+
api_key: APIKeyRequest,
|
233
|
+
) -> APIKeyResponse:
|
234
|
+
return zen_store().create_api_key(
|
235
|
+
service_account_id=service_account_id,
|
236
|
+
api_key=api_key,
|
237
|
+
)
|
238
|
+
|
236
239
|
service_account = zen_store().get_service_account(service_account_id)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
240
|
+
|
241
|
+
return verify_permissions_and_create_entity(
|
242
|
+
request_model=api_key,
|
243
|
+
create_method=create_api_key_wrapper,
|
244
|
+
surrogate_models=[service_account],
|
241
245
|
)
|
242
|
-
return created_api_key
|
243
246
|
|
244
247
|
|
245
248
|
@router.get(
|
246
249
|
"/{service_account_id}" + API_KEYS + "/{api_key_name_or_id}",
|
247
|
-
response_model=APIKeyResponse,
|
248
250
|
responses={401: error_response, 404: error_response, 422: error_response},
|
249
251
|
)
|
250
252
|
@handle_exceptions
|
@@ -278,7 +280,6 @@ def get_api_key(
|
|
278
280
|
|
279
281
|
@router.get(
|
280
282
|
"/{service_account_id}" + API_KEYS,
|
281
|
-
response_model=Page[APIKeyResponse],
|
282
283
|
responses={401: error_response, 404: error_response, 422: error_response},
|
283
284
|
)
|
284
285
|
@handle_exceptions
|
@@ -313,7 +314,6 @@ def list_api_keys(
|
|
313
314
|
|
314
315
|
@router.put(
|
315
316
|
"/{service_account_id}" + API_KEYS + "/{api_key_name_or_id}",
|
316
|
-
response_model=APIKeyResponse,
|
317
317
|
responses={401: error_response, 409: error_response, 422: error_response},
|
318
318
|
)
|
319
319
|
@handle_exceptions
|
@@ -348,7 +348,6 @@ def update_api_key(
|
|
348
348
|
+ API_KEYS
|
349
349
|
+ "/{api_key_name_or_id}"
|
350
350
|
+ API_KEY_ROTATE,
|
351
|
-
response_model=APIKeyResponse,
|
352
351
|
responses={401: error_response, 409: error_response, 422: error_response},
|
353
352
|
)
|
354
353
|
@handle_exceptions
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Endpoint definitions for service connectors."""
|
15
15
|
|
16
|
-
from typing import List, Optional
|
16
|
+
from typing import List, Optional, Union
|
17
17
|
from uuid import UUID
|
18
18
|
|
19
19
|
from fastapi import APIRouter, Depends, Security
|
@@ -22,6 +22,7 @@ from zenml.constants import (
|
|
22
22
|
API,
|
23
23
|
SERVICE_CONNECTOR_CLIENT,
|
24
24
|
SERVICE_CONNECTOR_FULL_STACK,
|
25
|
+
SERVICE_CONNECTOR_RESOURCES,
|
25
26
|
SERVICE_CONNECTOR_TYPES,
|
26
27
|
SERVICE_CONNECTOR_VERIFY,
|
27
28
|
SERVICE_CONNECTORS,
|
@@ -44,6 +45,7 @@ from zenml.service_connectors.service_connector_utils import (
|
|
44
45
|
from zenml.zen_server.auth import AuthContext, authorize
|
45
46
|
from zenml.zen_server.exceptions import error_response
|
46
47
|
from zenml.zen_server.rbac.endpoint_utils import (
|
48
|
+
verify_permissions_and_create_entity,
|
47
49
|
verify_permissions_and_delete_entity,
|
48
50
|
verify_permissions_and_list_entities,
|
49
51
|
verify_permissions_and_update_entity,
|
@@ -57,6 +59,7 @@ from zenml.zen_server.rbac.utils import (
|
|
57
59
|
verify_permission,
|
58
60
|
verify_permission_for_model,
|
59
61
|
)
|
62
|
+
from zenml.zen_server.routers.projects_endpoints import workspace_router
|
60
63
|
from zenml.zen_server.utils import (
|
61
64
|
handle_exceptions,
|
62
65
|
make_dependable,
|
@@ -76,31 +79,73 @@ types_router = APIRouter(
|
|
76
79
|
)
|
77
80
|
|
78
81
|
|
82
|
+
@router.post(
|
83
|
+
"",
|
84
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
85
|
+
)
|
86
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
87
|
+
# and can be removed after the migration
|
88
|
+
@workspace_router.post(
|
89
|
+
"/{project_name_or_id}" + SERVICE_CONNECTORS,
|
90
|
+
responses={401: error_response, 409: error_response, 422: error_response},
|
91
|
+
deprecated=True,
|
92
|
+
tags=["service_connectors"],
|
93
|
+
)
|
94
|
+
@handle_exceptions
|
95
|
+
def create_service_connector(
|
96
|
+
connector: ServiceConnectorRequest,
|
97
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
98
|
+
_: AuthContext = Security(authorize),
|
99
|
+
) -> ServiceConnectorResponse:
|
100
|
+
"""Creates a service connector.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
connector: Service connector to register.
|
104
|
+
project_name_or_id: Optional name or ID of the project.
|
105
|
+
|
106
|
+
Returns:
|
107
|
+
The created service connector.
|
108
|
+
"""
|
109
|
+
return verify_permissions_and_create_entity(
|
110
|
+
request_model=connector,
|
111
|
+
create_method=zen_store().create_service_connector,
|
112
|
+
)
|
113
|
+
|
114
|
+
|
79
115
|
@router.get(
|
80
116
|
"",
|
81
|
-
response_model=Page[ServiceConnectorResponse],
|
82
117
|
responses={401: error_response, 404: error_response, 422: error_response},
|
83
118
|
)
|
119
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
120
|
+
# and can be removed after the migration
|
121
|
+
@workspace_router.get(
|
122
|
+
"/{project_name_or_id}" + SERVICE_CONNECTORS,
|
123
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
124
|
+
deprecated=True,
|
125
|
+
tags=["service_connectors"],
|
126
|
+
)
|
84
127
|
@handle_exceptions
|
85
128
|
def list_service_connectors(
|
86
129
|
connector_filter_model: ServiceConnectorFilter = Depends(
|
87
130
|
make_dependable(ServiceConnectorFilter)
|
88
131
|
),
|
132
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
89
133
|
expand_secrets: bool = True,
|
90
134
|
hydrate: bool = False,
|
91
135
|
_: AuthContext = Security(authorize),
|
92
136
|
) -> Page[ServiceConnectorResponse]:
|
93
|
-
"""Get a list of all service connectors
|
137
|
+
"""Get a list of all service connectors.
|
94
138
|
|
95
139
|
Args:
|
96
140
|
connector_filter_model: Filter model used for pagination, sorting,
|
97
141
|
filtering
|
142
|
+
project_name_or_id: Optional name or ID of the project to filter by.
|
98
143
|
expand_secrets: Whether to expand secrets or not.
|
99
144
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
100
145
|
by including metadata fields in the response.
|
101
146
|
|
102
147
|
Returns:
|
103
|
-
Page with list of service connectors
|
148
|
+
Page with list of service connectors matching the filter criteria.
|
104
149
|
"""
|
105
150
|
connectors = verify_permissions_and_list_entities(
|
106
151
|
filter_model=connector_filter_model,
|
@@ -143,7 +188,6 @@ def list_service_connectors(
|
|
143
188
|
|
144
189
|
@router.get(
|
145
190
|
"/{connector_id}",
|
146
|
-
response_model=ServiceConnectorResponse,
|
147
191
|
responses={401: error_response, 404: error_response, 422: error_response},
|
148
192
|
)
|
149
193
|
@handle_exceptions
|
@@ -186,7 +230,6 @@ def get_service_connector(
|
|
186
230
|
|
187
231
|
@router.put(
|
188
232
|
"/{connector_id}",
|
189
|
-
response_model=ServiceConnectorResponse,
|
190
233
|
responses={401: error_response, 404: error_response, 422: error_response},
|
191
234
|
)
|
192
235
|
@handle_exceptions
|
@@ -235,7 +278,6 @@ def delete_service_connector(
|
|
235
278
|
|
236
279
|
@router.post(
|
237
280
|
SERVICE_CONNECTOR_VERIFY,
|
238
|
-
response_model=ServiceConnectorResourcesModel,
|
239
281
|
responses={401: error_response, 409: error_response, 422: error_response},
|
240
282
|
)
|
241
283
|
@handle_exceptions
|
@@ -259,9 +301,7 @@ def validate_and_verify_service_connector_config(
|
|
259
301
|
The list of resources that the service connector configuration has
|
260
302
|
access to.
|
261
303
|
"""
|
262
|
-
|
263
|
-
resource_type=ResourceType.SERVICE_CONNECTOR, action=Action.CREATE
|
264
|
-
)
|
304
|
+
verify_permission_for_model(model=connector, action=Action.CREATE)
|
265
305
|
|
266
306
|
return zen_store().verify_service_connector_config(
|
267
307
|
service_connector=connector,
|
@@ -269,9 +309,52 @@ def validate_and_verify_service_connector_config(
|
|
269
309
|
)
|
270
310
|
|
271
311
|
|
312
|
+
@router.get(
|
313
|
+
SERVICE_CONNECTOR_RESOURCES,
|
314
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
315
|
+
)
|
316
|
+
# TODO: the workspace scoped endpoint is only kept for dashboard compatibility
|
317
|
+
# and can be removed after the migration
|
318
|
+
@workspace_router.get(
|
319
|
+
"/{project_name_or_id}" + SERVICE_CONNECTOR_RESOURCES,
|
320
|
+
responses={401: error_response, 404: error_response, 422: error_response},
|
321
|
+
deprecated=True,
|
322
|
+
tags=["service_connectors"],
|
323
|
+
)
|
324
|
+
@handle_exceptions
|
325
|
+
def list_service_connector_resources(
|
326
|
+
filter_model: ServiceConnectorFilter = Depends(
|
327
|
+
make_dependable(ServiceConnectorFilter)
|
328
|
+
),
|
329
|
+
project_name_or_id: Optional[Union[str, UUID]] = None,
|
330
|
+
auth_context: AuthContext = Security(authorize),
|
331
|
+
) -> List[ServiceConnectorResourcesModel]:
|
332
|
+
"""List resources that can be accessed by service connectors.
|
333
|
+
|
334
|
+
Args:
|
335
|
+
filter_model: The filter model to use when fetching service
|
336
|
+
connectors.
|
337
|
+
project_name_or_id: Optional name or ID of the project.
|
338
|
+
auth_context: Authentication context.
|
339
|
+
|
340
|
+
Returns:
|
341
|
+
The matching list of resources that available service
|
342
|
+
connectors have access to.
|
343
|
+
"""
|
344
|
+
allowed_ids = get_allowed_resource_ids(
|
345
|
+
resource_type=ResourceType.SERVICE_CONNECTOR
|
346
|
+
)
|
347
|
+
filter_model.configure_rbac(
|
348
|
+
authenticated_user_id=auth_context.user.id, id=allowed_ids
|
349
|
+
)
|
350
|
+
|
351
|
+
return zen_store().list_service_connector_resources(
|
352
|
+
filter_model=filter_model,
|
353
|
+
)
|
354
|
+
|
355
|
+
|
272
356
|
@router.put(
|
273
357
|
"/{connector_id}" + SERVICE_CONNECTOR_VERIFY,
|
274
|
-
response_model=ServiceConnectorResourcesModel,
|
275
358
|
responses={401: error_response, 404: error_response, 422: error_response},
|
276
359
|
)
|
277
360
|
@handle_exceptions
|
@@ -313,7 +396,6 @@ def validate_and_verify_service_connector(
|
|
313
396
|
|
314
397
|
@router.get(
|
315
398
|
"/{connector_id}" + SERVICE_CONNECTOR_CLIENT,
|
316
|
-
response_model=ServiceConnectorResponse,
|
317
399
|
responses={401: error_response, 404: error_response, 422: error_response},
|
318
400
|
)
|
319
401
|
@handle_exceptions
|
@@ -351,7 +433,6 @@ def get_service_connector_client(
|
|
351
433
|
|
352
434
|
@types_router.get(
|
353
435
|
"",
|
354
|
-
response_model=List[ServiceConnectorTypeModel],
|
355
436
|
responses={401: error_response, 404: error_response, 422: error_response},
|
356
437
|
)
|
357
438
|
@handle_exceptions
|
@@ -382,7 +463,6 @@ def list_service_connector_types(
|
|
382
463
|
|
383
464
|
@types_router.get(
|
384
465
|
"/{connector_type}",
|
385
|
-
response_model=ServiceConnectorTypeModel,
|
386
466
|
responses={401: error_response, 404: error_response, 422: error_response},
|
387
467
|
)
|
388
468
|
@handle_exceptions
|