zenml-nightly 0.58.2.dev20240623__py3-none-any.whl → 0.61.0.dev20240712__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.
- README.md +30 -9
- RELEASE_NOTES.md +240 -0
- zenml/VERSION +1 -1
- zenml/actions/base_action.py +177 -174
- zenml/actions/pipeline_run/pipeline_run_action.py +28 -23
- zenml/analytics/enums.py +3 -0
- zenml/artifact_stores/base_artifact_store.py +7 -1
- zenml/artifacts/utils.py +13 -10
- zenml/cli/__init__.py +28 -0
- zenml/cli/artifact.py +1 -2
- zenml/cli/integration.py +9 -8
- zenml/cli/server.py +6 -0
- zenml/cli/service_connectors.py +1 -0
- zenml/cli/stack.py +946 -39
- zenml/cli/stack_components.py +7 -0
- zenml/cli/text_utils.py +35 -1
- zenml/cli/utils.py +127 -10
- zenml/client.py +257 -72
- zenml/config/compiler.py +10 -9
- zenml/config/docker_settings.py +33 -14
- zenml/constants.py +11 -2
- zenml/container_registries/base_container_registry.py +1 -0
- zenml/enums.py +7 -0
- zenml/event_hub/base_event_hub.py +5 -5
- zenml/event_hub/event_hub.py +20 -14
- zenml/event_sources/base_event.py +0 -11
- zenml/event_sources/base_event_source.py +7 -0
- zenml/event_sources/webhooks/base_webhook_event_source.py +1 -4
- zenml/exceptions.py +4 -0
- zenml/hooks/hook_validators.py +2 -3
- zenml/integrations/aws/__init__.py +1 -0
- zenml/integrations/azure/__init__.py +1 -0
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +3 -3
- zenml/integrations/deepchecks/__init__.py +1 -0
- zenml/integrations/discord/__init__.py +1 -0
- zenml/integrations/evidently/__init__.py +1 -0
- zenml/integrations/facets/__init__.py +1 -0
- zenml/integrations/feast/__init__.py +1 -0
- zenml/integrations/gcp/__init__.py +3 -1
- zenml/integrations/gcp/google_credentials_mixin.py +1 -1
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +320 -64
- zenml/integrations/huggingface/__init__.py +1 -0
- zenml/integrations/integration.py +24 -0
- zenml/integrations/kubeflow/__init__.py +3 -0
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +1 -1
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +0 -1
- zenml/integrations/kubernetes/__init__.py +3 -1
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +4 -1
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +1 -0
- zenml/integrations/langchain/__init__.py +1 -0
- zenml/integrations/mlflow/__init__.py +4 -2
- zenml/integrations/neural_prophet/__init__.py +1 -0
- zenml/integrations/polars/__init__.py +1 -0
- zenml/integrations/prodigy/__init__.py +1 -0
- zenml/integrations/pycaret/__init__.py +6 -0
- zenml/integrations/registry.py +37 -0
- zenml/integrations/s3/artifact_stores/s3_artifact_store.py +93 -9
- zenml/integrations/seldon/__init__.py +1 -0
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -0
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +2 -2
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +1 -1
- zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
- zenml/integrations/skypilot_aws/__init__.py +2 -1
- zenml/integrations/skypilot_azure/__init__.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/__init__.py +1 -1
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +1 -1
- zenml/integrations/slack/__init__.py +1 -0
- zenml/integrations/tekton/__init__.py +1 -0
- zenml/integrations/tensorboard/__init__.py +0 -1
- zenml/integrations/tensorflow/__init__.py +18 -6
- zenml/integrations/wandb/__init__.py +1 -0
- zenml/logging/step_logging.py +54 -51
- zenml/models/__init__.py +28 -0
- zenml/models/v2/core/action.py +276 -0
- zenml/models/v2/core/component.py +18 -0
- zenml/models/v2/core/model.py +1 -2
- zenml/models/v2/core/service_connector.py +17 -0
- zenml/models/v2/core/stack.py +31 -0
- zenml/models/v2/core/trigger.py +182 -141
- zenml/models/v2/misc/full_stack.py +97 -0
- zenml/models/v2/misc/stack_deployment.py +86 -0
- zenml/new/pipelines/pipeline.py +14 -4
- zenml/new/pipelines/pipeline_decorator.py +1 -2
- zenml/new/pipelines/run_utils.py +1 -12
- zenml/new/steps/step_decorator.py +2 -3
- zenml/orchestrators/input_utils.py +3 -6
- zenml/pipelines/base_pipeline.py +0 -2
- zenml/pipelines/pipeline_decorator.py +1 -2
- zenml/stack/stack.py +3 -6
- zenml/stack/stack_component.py +4 -0
- zenml/stack_deployments/__init__.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +254 -0
- zenml/stack_deployments/gcp_stack_deployment.py +260 -0
- zenml/stack_deployments/stack_deployment.py +208 -0
- zenml/stack_deployments/utils.py +44 -0
- zenml/steps/base_step.py +1 -2
- zenml/steps/step_decorator.py +1 -2
- zenml/types.py +10 -1
- zenml/utils/function_utils.py +1 -1
- zenml/utils/pagination_utils.py +7 -5
- zenml/utils/pipeline_docker_image_builder.py +117 -73
- zenml/utils/pydantic_utils.py +6 -5
- zenml/zen_server/cloud_utils.py +18 -3
- zenml/zen_server/dashboard/assets/{404-CDPQCl4D.js → 404-DpJaNHKF.js} +1 -1
- zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +85 -0
- zenml/zen_server/dashboard/assets/{@react-router-DYovave8.js → @react-router-CO-OsFwI.js} +2 -2
- zenml/zen_server/dashboard/assets/{@reactflow-CHBapDaj.js → @reactflow-DJfzkHO1.js} +2 -2
- zenml/zen_server/dashboard/assets/@tanstack-DYiOyJUL.js +22 -0
- zenml/zen_server/dashboard/assets/AwarenessChannel-BYDLT2xC.js +1 -0
- zenml/zen_server/dashboard/assets/{CodeSnippet-BidtnWOi.js → CodeSnippet-BkOuRmyq.js} +2 -2
- zenml/zen_server/dashboard/assets/Commands-ZvWR1BRs.js +1 -0
- zenml/zen_server/dashboard/assets/CopyButton-DVwLkafa.js +2 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-BOuez-fG.js → CsvVizualization-C2IiqX4I.js} +7 -7
- zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +1 -0
- zenml/zen_server/dashboard/assets/EmptyState-BMLnFVlB.js +1 -0
- zenml/zen_server/dashboard/assets/Error-CqX0VqW_.js +1 -0
- zenml/zen_server/dashboard/assets/ExecutionStatus-BoLUXR9t.js +1 -0
- zenml/zen_server/dashboard/assets/Helpbox-LFydyVwh.js +1 -0
- zenml/zen_server/dashboard/assets/Infobox-DnENC0sh.js +1 -0
- zenml/zen_server/dashboard/assets/InlineAvatar-CbJtYr0t.js +1 -0
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-DsB2QZiK.js → MarkdownVisualization-xp3hhULl.js} +2 -2
- zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +1 -0
- zenml/zen_server/dashboard/assets/PasswordChecker-DUveqlva.js +1 -0
- zenml/zen_server/dashboard/assets/SetPassword-BYBdbQDo.js +1 -0
- zenml/zen_server/dashboard/assets/SuccessStep-Nx743hll.js +1 -0
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DnM-c11H.js → UpdatePasswordSchemas-DF9gSzE0.js} +1 -1
- zenml/zen_server/dashboard/assets/{aws-t0gKCj_R.js → aws-BgKTfTfx.js} +1 -1
- zenml/zen_server/dashboard/assets/{check-circle-BVvhm5dy.js → check-circle-i56092KI.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-down-zcvCWmyP.js → chevron-down-D_ZlKMqH.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-CJ50E9Gr.js → chevron-right-double-BiEMg7rd.js} +1 -1
- zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +1 -0
- zenml/zen_server/dashboard/assets/{copy-BRhQz3j-.js → copy-BXNk6BjL.js} +1 -1
- zenml/zen_server/dashboard/assets/{database-CRRnyFWh.js → database-1xWSgZfO.js} +1 -1
- zenml/zen_server/dashboard/assets/{docker-BAonhm6G.js → docker-CQMVm_4d.js} +1 -1
- zenml/zen_server/dashboard/assets/{file-text-CbVERUON.js → file-text-CqD_iu6l.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-B8rqCvqn.js → help-bu_DgLKI.js} +1 -1
- zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +1 -0
- zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +55 -0
- zenml/zen_server/dashboard/assets/index-inApY3KQ.css +1 -0
- zenml/zen_server/dashboard/assets/index-rK_Wuy2W.js +1 -0
- zenml/zen_server/dashboard/assets/index.esm-Corw4lXQ.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-wzzl23C6.js → login-mutation-BUnVASxp.js} +1 -1
- zenml/zen_server/dashboard/assets/not-found-B4VnX8gK.js +1 -0
- zenml/zen_server/dashboard/assets/package-CsUhPmou.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BmkSiYeQ.js → page-3efNCDeb.js} +2 -2
- zenml/zen_server/dashboard/assets/page-7zTHbhhI.js +1 -0
- zenml/zen_server/dashboard/assets/page-BEs6jK71.js +1 -0
- zenml/zen_server/dashboard/assets/page-BpSqIf4B.js +1 -0
- zenml/zen_server/dashboard/assets/{page-AQKopn_4.js → page-Bx6o0ARS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-C43QGHTt.js +9 -0
- zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +1 -0
- zenml/zen_server/dashboard/assets/page-CRTJ0UuR.js +1 -0
- zenml/zen_server/dashboard/assets/page-CUZIGO-3.js +1 -0
- zenml/zen_server/dashboard/assets/page-CaopxiU1.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CuT1SUik.js → page-Cx67M0QT.js} +1 -1
- zenml/zen_server/dashboard/assets/page-D7Z399xy.js +1 -0
- zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BzVZGExK.js → page-DKlIdAe5.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Bi5AI0S7.js → page-DMOYZppS.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +2 -0
- zenml/zen_server/dashboard/assets/{page-BW6Ket3a.js → page-Dc_7KMQE.js} +1 -1
- zenml/zen_server/dashboard/assets/page-DvCvroOM.js +1 -0
- zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +1 -0
- zenml/zen_server/dashboard/assets/page-JyfeDUfu.js +1 -0
- zenml/zen_server/dashboard/assets/{page-yN4rZ-ZS.js → page-Sxn82W-5.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TKXERe16.js +1 -0
- zenml/zen_server/dashboard/assets/page-Xu8JEjSU.js +1 -0
- zenml/zen_server/dashboard/assets/{play-circle-DK5QMJyp.js → play-circle-CNtZKDnW.js} +1 -1
- zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +1 -0
- zenml/zen_server/dashboard/assets/{terminal-B2ovgWuz.js → terminal-By9cErXc.js} +1 -1
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-0Wgz8pUE.js → update-server-settings-mutation-CR8e3Sir.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-6_xv0WJS.js → url-DuQMeqYA.js} +1 -1
- zenml/zen_server/dashboard/assets/{zod-DrZvVLjd.js → zod-BhoGpZ63.js} +1 -1
- zenml/zen_server/dashboard/index.html +7 -7
- zenml/zen_server/dashboard_legacy/asset-manifest.json +4 -4
- zenml/zen_server/dashboard_legacy/index.html +1 -1
- zenml/zen_server/dashboard_legacy/{precache-manifest.f4abc5b7cfa7d90c1caf5521918e29a8.js → precache-manifest.c8c57fb0d2132b1d3c2119e776b7dfb3.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js → main.382439a7.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.ac2f17d0.chunk.js.map → main.382439a7.chunk.js.map} +1 -1
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +11 -5
- zenml/zen_server/pipeline_deployment/utils.py +57 -44
- zenml/zen_server/rbac/models.py +1 -0
- zenml/zen_server/rbac/utils.py +22 -1
- zenml/zen_server/rbac/zenml_cloud_rbac.py +11 -5
- zenml/zen_server/routers/actions_endpoints.py +324 -0
- zenml/zen_server/routers/stack_deployment_endpoints.py +158 -0
- zenml/zen_server/routers/triggers_endpoints.py +30 -158
- zenml/zen_server/routers/workspaces_endpoints.py +64 -0
- zenml/zen_server/zen_server_api.py +4 -0
- zenml/zen_stores/migrations/utils.py +1 -1
- zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
- zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
- zenml/zen_stores/rest_zen_store.py +248 -8
- zenml/zen_stores/schemas/__init__.py +2 -0
- zenml/zen_stores/schemas/action_schemas.py +192 -0
- zenml/zen_stores/schemas/stack_schemas.py +10 -0
- zenml/zen_stores/schemas/step_run_schemas.py +27 -11
- zenml/zen_stores/schemas/trigger_schemas.py +43 -50
- zenml/zen_stores/schemas/user_schemas.py +10 -2
- zenml/zen_stores/schemas/workspace_schemas.py +5 -0
- zenml/zen_stores/sql_zen_store.py +540 -36
- zenml/zen_stores/zen_store_interface.py +165 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/METADATA +33 -11
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/RECORD +213 -193
- zenml/zen_server/dashboard/assets/@radix-C9DBgJhe.js +0 -77
- zenml/zen_server/dashboard/assets/@tanstack-CEbkxrhX.js +0 -30
- zenml/zen_server/dashboard/assets/AwarenessChannel-nXGpmj_f.js +0 -1
- zenml/zen_server/dashboard/assets/Cards-nwsvQLVS.js +0 -1
- zenml/zen_server/dashboard/assets/Commands-DuIWKg_Q.js +0 -1
- zenml/zen_server/dashboard/assets/CopyButton-B_YSm-Ds.js +0 -2
- zenml/zen_server/dashboard/assets/DisplayDate-BdguISQF.js +0 -1
- zenml/zen_server/dashboard/assets/EmptyState-BkooiGtL.js +0 -1
- zenml/zen_server/dashboard/assets/Error-B6M0dPph.js +0 -1
- zenml/zen_server/dashboard/assets/Helpbox-BQoqCm04.js +0 -1
- zenml/zen_server/dashboard/assets/Infobox-Ce9mefqU.js +0 -1
- zenml/zen_server/dashboard/assets/InlineAvatar-DGf3dVhV.js +0 -1
- zenml/zen_server/dashboard/assets/PageHeader-DGaemzjc.js +0 -1
- zenml/zen_server/dashboard/assets/Pagination-DVYfBCCc.js +0 -1
- zenml/zen_server/dashboard/assets/PasswordChecker-DSLBp7Vl.js +0 -1
- zenml/zen_server/dashboard/assets/SetPassword-B5s7DJug.js +0 -1
- zenml/zen_server/dashboard/assets/SuccessStep-ZzczaM7g.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-Ba_ShBR5.js +0 -1
- zenml/zen_server/dashboard/assets/index-CWJ3xbIf.css +0 -1
- zenml/zen_server/dashboard/assets/index-QORVVTMN.js +0 -55
- zenml/zen_server/dashboard/assets/index.esm-F7nqy9zY.js +0 -1
- zenml/zen_server/dashboard/assets/not-found-Dh2la7kh.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-5jAKoO.js +0 -1
- zenml/zen_server/dashboard/assets/page-B-vWk8a6.js +0 -1
- zenml/zen_server/dashboard/assets/page-B0BrqfS8.js +0 -1
- zenml/zen_server/dashboard/assets/page-BQxVFlUl.js +0 -1
- zenml/zen_server/dashboard/assets/page-ByrHy6Ss.js +0 -1
- zenml/zen_server/dashboard/assets/page-CPtY4Kv_.js +0 -1
- zenml/zen_server/dashboard/assets/page-CmmukLsl.js +0 -1
- zenml/zen_server/dashboard/assets/page-D2D-7qyr.js +0 -9
- zenml/zen_server/dashboard/assets/page-DAQQyLxT.js +0 -1
- zenml/zen_server/dashboard/assets/page-DHkUMl_E.js +0 -1
- zenml/zen_server/dashboard/assets/page-DZCbwOEs.js +0 -2
- zenml/zen_server/dashboard/assets/page-DdaIt20-.js +0 -1
- zenml/zen_server/dashboard/assets/page-LqLs24Ot.js +0 -1
- zenml/zen_server/dashboard/assets/page-lebv0c7C.js +0 -1
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.58.2.dev20240623.dist-info → zenml_nightly-0.61.0.dev20240712.dist-info}/entry_points.txt +0 -0
zenml/logging/step_logging.py
CHANGED
@@ -145,61 +145,64 @@ def fetch_logs(
|
|
145
145
|
)
|
146
146
|
|
147
147
|
artifact_store = _load_artifact_store(artifact_store_id, zen_store)
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
files = artifact_store.listdir(logs_uri)
|
152
|
-
if len(files) == 1:
|
153
|
-
return _read_file(
|
154
|
-
os.path.join(logs_uri, str(files[0])), offset, length
|
155
|
-
)
|
148
|
+
try:
|
149
|
+
if not artifact_store.isdir(logs_uri):
|
150
|
+
return _read_file(logs_uri, offset, length)
|
156
151
|
else:
|
157
|
-
|
158
|
-
files
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
152
|
+
files = artifact_store.listdir(logs_uri)
|
153
|
+
if len(files) == 1:
|
154
|
+
return _read_file(
|
155
|
+
os.path.join(logs_uri, str(files[0])), offset, length
|
156
|
+
)
|
157
|
+
else:
|
158
|
+
is_negative_offset = offset < 0
|
159
|
+
files.sort(reverse=is_negative_offset)
|
160
|
+
|
161
|
+
# search for the first file we need to read
|
162
|
+
latest_file_id = 0
|
163
|
+
for i, file in enumerate(files):
|
164
|
+
file_size: int = artifact_store.size(
|
165
|
+
os.path.join(logs_uri, str(file))
|
166
|
+
) # type: ignore[assignment]
|
167
|
+
|
168
|
+
if is_negative_offset:
|
169
|
+
if file_size >= -offset:
|
170
|
+
latest_file_id = -(i + 1)
|
171
|
+
break
|
172
|
+
else:
|
173
|
+
offset += file_size
|
171
174
|
else:
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
175
|
+
if file_size > offset:
|
176
|
+
latest_file_id = i
|
177
|
+
break
|
178
|
+
else:
|
179
|
+
offset -= file_size
|
180
|
+
|
181
|
+
# read the files according to pre-filtering
|
182
|
+
files.sort()
|
183
|
+
ret = []
|
184
|
+
for file in files[latest_file_id:]:
|
185
|
+
ret.append(
|
186
|
+
_read_file(
|
187
|
+
os.path.join(logs_uri, str(file)),
|
188
|
+
offset,
|
189
|
+
length,
|
190
|
+
)
|
191
|
+
)
|
192
|
+
offset = 0
|
193
|
+
length -= len(ret[-1])
|
194
|
+
if length <= 0:
|
195
|
+
# stop further reading, if the whole length is already read
|
176
196
|
break
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
ret = []
|
183
|
-
for file in files[latest_file_id:]:
|
184
|
-
ret.append(
|
185
|
-
_read_file(
|
186
|
-
os.path.join(logs_uri, str(file)),
|
187
|
-
offset,
|
188
|
-
length,
|
197
|
+
|
198
|
+
if not ret:
|
199
|
+
raise DoesNotExistException(
|
200
|
+
f"Folder '{logs_uri}' is empty in artifact store "
|
201
|
+
f"'{artifact_store.name}'."
|
189
202
|
)
|
190
|
-
)
|
191
|
-
|
192
|
-
|
193
|
-
if length <= 0:
|
194
|
-
# stop further reading, if the whole length is already read
|
195
|
-
break
|
196
|
-
|
197
|
-
if not ret:
|
198
|
-
raise DoesNotExistException(
|
199
|
-
f"Folder '{logs_uri}' is empty in artifact store "
|
200
|
-
f"'{artifact_store.name}'."
|
201
|
-
)
|
202
|
-
return "".join(ret)
|
203
|
+
return "".join(ret)
|
204
|
+
finally:
|
205
|
+
artifact_store.cleanup()
|
203
206
|
|
204
207
|
|
205
208
|
class StepLogsStorage:
|
zenml/models/__init__.py
CHANGED
@@ -51,6 +51,15 @@ from zenml.models.v2.base.filter import (
|
|
51
51
|
from zenml.models.v2.base.page import Page
|
52
52
|
|
53
53
|
# V2 Core
|
54
|
+
from zenml.models.v2.core.action import (
|
55
|
+
ActionFilter,
|
56
|
+
ActionRequest,
|
57
|
+
ActionResponse,
|
58
|
+
ActionResponseBody,
|
59
|
+
ActionResponseMetadata,
|
60
|
+
ActionResponseResources,
|
61
|
+
ActionUpdate,
|
62
|
+
)
|
54
63
|
from zenml.models.v2.core.action_flavor import (
|
55
64
|
ActionFlavorResponse,
|
56
65
|
ActionFlavorResponseBody,
|
@@ -318,6 +327,7 @@ from zenml.models.v2.misc.service_connector_type import (
|
|
318
327
|
ResourceTypeModel,
|
319
328
|
)
|
320
329
|
from zenml.models.v2.misc.server_models import ServerDatabaseType, ServerModel
|
330
|
+
from zenml.models.v2.misc.full_stack import FullStackRequest
|
321
331
|
from zenml.models.v2.core.trigger import (
|
322
332
|
TriggerRequest,
|
323
333
|
TriggerFilter,
|
@@ -377,10 +387,16 @@ from zenml.models.v2.core.server_settings import (
|
|
377
387
|
ServerSettingsResponseMetadata,
|
378
388
|
ServerSettingsUpdate,
|
379
389
|
)
|
390
|
+
from zenml.models.v2.misc.stack_deployment import (
|
391
|
+
DeployedStack,
|
392
|
+
StackDeploymentConfig,
|
393
|
+
StackDeploymentInfo,
|
394
|
+
)
|
380
395
|
|
381
396
|
# ----------------------------- Forward References -----------------------------
|
382
397
|
|
383
398
|
# V2
|
399
|
+
ActionResponseResources.model_rebuild()
|
384
400
|
APIKeyResponseBody.model_rebuild()
|
385
401
|
ArtifactVersionRequest.model_rebuild()
|
386
402
|
ArtifactVersionResponseBody.model_rebuild()
|
@@ -395,6 +411,7 @@ EventSourceResponseMetadata.model_rebuild()
|
|
395
411
|
EventSourceResponseResources.model_rebuild()
|
396
412
|
FlavorResponseBody.model_rebuild()
|
397
413
|
FlavorResponseMetadata.model_rebuild()
|
414
|
+
FullStackRequest.model_rebuild()
|
398
415
|
LazyArtifactVersionResponse.model_rebuild()
|
399
416
|
LazyRunMetadataResponse.model_rebuild()
|
400
417
|
ModelResponseBody.model_rebuild()
|
@@ -470,6 +487,13 @@ __all__ = [
|
|
470
487
|
"UUIDFilter",
|
471
488
|
"Page",
|
472
489
|
# V2 Core
|
490
|
+
"ActionFilter",
|
491
|
+
"ActionRequest",
|
492
|
+
"ActionResponse",
|
493
|
+
"ActionResponseBody",
|
494
|
+
"ActionResponseMetadata",
|
495
|
+
"ActionResponseResources",
|
496
|
+
"ActionUpdate",
|
473
497
|
"ActionFlavorResponse",
|
474
498
|
"ActionFlavorResponseBody",
|
475
499
|
"ActionFlavorResponseMetadata",
|
@@ -684,11 +708,13 @@ __all__ = [
|
|
684
708
|
"WorkspaceResponseMetadata",
|
685
709
|
# V2 Misc
|
686
710
|
"AuthenticationMethodModel",
|
711
|
+
"DeployedStack",
|
687
712
|
"ServiceConnectorResourcesModel",
|
688
713
|
"ServiceConnectorTypeModel",
|
689
714
|
"ServiceConnectorTypedResourcesModel",
|
690
715
|
"ServiceConnectorRequirements",
|
691
716
|
"ResourceTypeModel",
|
717
|
+
"FullStackRequest",
|
692
718
|
"UserAuthModel",
|
693
719
|
"ExternalUserModel",
|
694
720
|
"BuildItem",
|
@@ -701,6 +727,8 @@ __all__ = [
|
|
701
727
|
"ServerModel",
|
702
728
|
"ServerDatabaseType",
|
703
729
|
"ServerDeploymentType",
|
730
|
+
"StackDeploymentConfig",
|
731
|
+
"StackDeploymentInfo",
|
704
732
|
"OAuthDeviceAuthorizationRequest",
|
705
733
|
"OAuthDeviceAuthorizationResponse",
|
706
734
|
"OAuthDeviceTokenRequest",
|
@@ -0,0 +1,276 @@
|
|
1
|
+
# Copyright (c) ZenML GmbH 2024. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at:
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
12
|
+
# or implied. See the License for the specific language governing
|
13
|
+
# permissions and limitations under the License.
|
14
|
+
"""Collection of all models concerning actions."""
|
15
|
+
|
16
|
+
import copy
|
17
|
+
from typing import (
|
18
|
+
TYPE_CHECKING,
|
19
|
+
Any,
|
20
|
+
Dict,
|
21
|
+
Optional,
|
22
|
+
TypeVar,
|
23
|
+
)
|
24
|
+
from uuid import UUID
|
25
|
+
|
26
|
+
from pydantic import Field
|
27
|
+
|
28
|
+
from zenml.constants import STR_FIELD_MAX_LENGTH
|
29
|
+
from zenml.enums import PluginSubType
|
30
|
+
from zenml.models.v2.base.base import BaseUpdate
|
31
|
+
from zenml.models.v2.base.scoped import (
|
32
|
+
WorkspaceScopedFilter,
|
33
|
+
WorkspaceScopedRequest,
|
34
|
+
WorkspaceScopedResponse,
|
35
|
+
WorkspaceScopedResponseBody,
|
36
|
+
WorkspaceScopedResponseMetadata,
|
37
|
+
WorkspaceScopedResponseResources,
|
38
|
+
)
|
39
|
+
from zenml.models.v2.core.user import UserResponse
|
40
|
+
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
from zenml.zen_stores.schemas import BaseSchema
|
43
|
+
|
44
|
+
AnySchema = TypeVar("AnySchema", bound=BaseSchema)
|
45
|
+
|
46
|
+
|
47
|
+
# ------------------ Request Model ------------------
|
48
|
+
|
49
|
+
|
50
|
+
class ActionRequest(WorkspaceScopedRequest):
|
51
|
+
"""Model for creating a new action."""
|
52
|
+
|
53
|
+
name: str = Field(
|
54
|
+
title="The name of the action.", max_length=STR_FIELD_MAX_LENGTH
|
55
|
+
)
|
56
|
+
description: str = Field(
|
57
|
+
default="",
|
58
|
+
title="The description of the action",
|
59
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
60
|
+
)
|
61
|
+
flavor: str = Field(
|
62
|
+
title="The flavor of the action.",
|
63
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
64
|
+
)
|
65
|
+
plugin_subtype: PluginSubType = Field(
|
66
|
+
title="The subtype of the action.",
|
67
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
68
|
+
)
|
69
|
+
configuration: Dict[str, Any] = Field(
|
70
|
+
title="The configuration for the action.",
|
71
|
+
)
|
72
|
+
service_account_id: UUID = Field(
|
73
|
+
title="The service account that is used to execute the action.",
|
74
|
+
)
|
75
|
+
auth_window: Optional[int] = Field(
|
76
|
+
default=None,
|
77
|
+
title="The time window in minutes for which the service account is "
|
78
|
+
"authorized to execute the action. Set this to 0 to authorize the "
|
79
|
+
"service account indefinitely (not recommended). If not set, a "
|
80
|
+
"default value defined for each individual action type is used.",
|
81
|
+
)
|
82
|
+
|
83
|
+
|
84
|
+
# ------------------ Update Model ------------------
|
85
|
+
|
86
|
+
|
87
|
+
class ActionUpdate(BaseUpdate):
|
88
|
+
"""Update model for actions."""
|
89
|
+
|
90
|
+
name: Optional[str] = Field(
|
91
|
+
default=None,
|
92
|
+
title="The new name for the action.",
|
93
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
94
|
+
)
|
95
|
+
description: Optional[str] = Field(
|
96
|
+
default=None,
|
97
|
+
title="The new description for the action.",
|
98
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
99
|
+
)
|
100
|
+
configuration: Optional[Dict[str, Any]] = Field(
|
101
|
+
default=None,
|
102
|
+
title="The configuration for the action.",
|
103
|
+
)
|
104
|
+
service_account_id: Optional[UUID] = Field(
|
105
|
+
default=None,
|
106
|
+
title="The service account that is used to execute the action.",
|
107
|
+
)
|
108
|
+
auth_window: Optional[int] = Field(
|
109
|
+
default=None,
|
110
|
+
title="The time window in minutes for which the service account is "
|
111
|
+
"authorized to execute the action. Set this to 0 to authorize the "
|
112
|
+
"service account indefinitely (not recommended). If not set, a "
|
113
|
+
"default value defined for each individual action type is used.",
|
114
|
+
)
|
115
|
+
|
116
|
+
@classmethod
|
117
|
+
def from_response(cls, response: "ActionResponse") -> "ActionUpdate":
|
118
|
+
"""Create an update model from a response model.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
response: The response model to create the update model from.
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
The update model.
|
125
|
+
"""
|
126
|
+
return ActionUpdate(
|
127
|
+
configuration=copy.deepcopy(response.configuration),
|
128
|
+
)
|
129
|
+
|
130
|
+
|
131
|
+
# ------------------ Response Model ------------------
|
132
|
+
|
133
|
+
|
134
|
+
class ActionResponseBody(WorkspaceScopedResponseBody):
|
135
|
+
"""Response body for actions."""
|
136
|
+
|
137
|
+
flavor: str = Field(
|
138
|
+
title="The flavor of the action.",
|
139
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
140
|
+
)
|
141
|
+
plugin_subtype: PluginSubType = Field(
|
142
|
+
title="The subtype of the action.",
|
143
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
144
|
+
)
|
145
|
+
|
146
|
+
|
147
|
+
class ActionResponseMetadata(WorkspaceScopedResponseMetadata):
|
148
|
+
"""Response metadata for actions."""
|
149
|
+
|
150
|
+
description: str = Field(
|
151
|
+
default="",
|
152
|
+
title="The description of the action.",
|
153
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
154
|
+
)
|
155
|
+
configuration: Dict[str, Any] = Field(
|
156
|
+
title="The configuration for the action.",
|
157
|
+
)
|
158
|
+
auth_window: int = Field(
|
159
|
+
title="The time window in minutes for which the service account is "
|
160
|
+
"authorized to execute the action."
|
161
|
+
)
|
162
|
+
|
163
|
+
|
164
|
+
class ActionResponseResources(WorkspaceScopedResponseResources):
|
165
|
+
"""Class for all resource models associated with the action entity."""
|
166
|
+
|
167
|
+
service_account: UserResponse = Field(
|
168
|
+
title="The service account that is used to execute the action.",
|
169
|
+
)
|
170
|
+
|
171
|
+
|
172
|
+
class ActionResponse(
|
173
|
+
WorkspaceScopedResponse[
|
174
|
+
ActionResponseBody, ActionResponseMetadata, ActionResponseResources
|
175
|
+
]
|
176
|
+
):
|
177
|
+
"""Response model for actions."""
|
178
|
+
|
179
|
+
name: str = Field(
|
180
|
+
title="The name of the action.",
|
181
|
+
max_length=STR_FIELD_MAX_LENGTH,
|
182
|
+
)
|
183
|
+
|
184
|
+
def get_hydrated_version(self) -> "ActionResponse":
|
185
|
+
"""Get the hydrated version of this action.
|
186
|
+
|
187
|
+
Returns:
|
188
|
+
An instance of the same entity with the metadata field attached.
|
189
|
+
"""
|
190
|
+
from zenml.client import Client
|
191
|
+
|
192
|
+
return Client().zen_store.get_action(self.id)
|
193
|
+
|
194
|
+
# Body and metadata properties
|
195
|
+
@property
|
196
|
+
def flavor(self) -> str:
|
197
|
+
"""The `flavor` property.
|
198
|
+
|
199
|
+
Returns:
|
200
|
+
the value of the property.
|
201
|
+
"""
|
202
|
+
return self.get_body().flavor
|
203
|
+
|
204
|
+
@property
|
205
|
+
def plugin_subtype(self) -> PluginSubType:
|
206
|
+
"""The `plugin_subtype` property.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
the value of the property.
|
210
|
+
"""
|
211
|
+
return self.get_body().plugin_subtype
|
212
|
+
|
213
|
+
@property
|
214
|
+
def description(self) -> str:
|
215
|
+
"""The `description` property.
|
216
|
+
|
217
|
+
Returns:
|
218
|
+
the value of the property.
|
219
|
+
"""
|
220
|
+
return self.get_metadata().description
|
221
|
+
|
222
|
+
@property
|
223
|
+
def auth_window(self) -> int:
|
224
|
+
"""The `auth_window` property.
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
the value of the property.
|
228
|
+
"""
|
229
|
+
return self.get_metadata().auth_window
|
230
|
+
|
231
|
+
@property
|
232
|
+
def configuration(self) -> Dict[str, Any]:
|
233
|
+
"""The `configuration` property.
|
234
|
+
|
235
|
+
Returns:
|
236
|
+
the value of the property.
|
237
|
+
"""
|
238
|
+
return self.get_metadata().configuration
|
239
|
+
|
240
|
+
def set_configuration(self, configuration: Dict[str, Any]) -> None:
|
241
|
+
"""Set the `configuration` property.
|
242
|
+
|
243
|
+
Args:
|
244
|
+
configuration: The value to set.
|
245
|
+
"""
|
246
|
+
self.get_metadata().configuration = configuration
|
247
|
+
|
248
|
+
# Resource properties
|
249
|
+
@property
|
250
|
+
def service_account(self) -> "UserResponse":
|
251
|
+
"""The `service_account` property.
|
252
|
+
|
253
|
+
Returns:
|
254
|
+
the value of the property.
|
255
|
+
"""
|
256
|
+
return self.get_resources().service_account
|
257
|
+
|
258
|
+
|
259
|
+
# ------------------ Filter Model ------------------
|
260
|
+
|
261
|
+
|
262
|
+
class ActionFilter(WorkspaceScopedFilter):
|
263
|
+
"""Model to enable advanced filtering of all actions."""
|
264
|
+
|
265
|
+
name: Optional[str] = Field(
|
266
|
+
default=None,
|
267
|
+
description="Name of the action.",
|
268
|
+
)
|
269
|
+
flavor: Optional[str] = Field(
|
270
|
+
default=None,
|
271
|
+
title="The flavor of the action.",
|
272
|
+
)
|
273
|
+
plugin_subtype: Optional[str] = Field(
|
274
|
+
default=None,
|
275
|
+
title="The subtype of the action.",
|
276
|
+
)
|
@@ -238,6 +238,24 @@ class ComponentResponse(
|
|
238
238
|
max_length=STR_FIELD_MAX_LENGTH,
|
239
239
|
)
|
240
240
|
|
241
|
+
def get_analytics_metadata(self) -> Dict[str, Any]:
|
242
|
+
"""Add the component labels to analytics metadata.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
Dict of analytics metadata.
|
246
|
+
"""
|
247
|
+
metadata = super().get_analytics_metadata()
|
248
|
+
|
249
|
+
if self.labels is not None:
|
250
|
+
metadata.update(
|
251
|
+
{
|
252
|
+
label[6:]: value
|
253
|
+
for label, value in self.labels.items()
|
254
|
+
if label.startswith("zenml:")
|
255
|
+
}
|
256
|
+
)
|
257
|
+
return metadata
|
258
|
+
|
241
259
|
def get_hydrated_version(self) -> "ComponentResponse":
|
242
260
|
"""Get the hydrated version of this component.
|
243
261
|
|
zenml/models/v2/core/model.py
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Models representing models."""
|
15
15
|
|
16
|
-
from functools import partial
|
17
16
|
from typing import TYPE_CHECKING, ClassVar, List, Optional, Union
|
18
17
|
from uuid import UUID
|
19
18
|
|
@@ -303,7 +302,7 @@ class ModelResponse(
|
|
303
302
|
|
304
303
|
client = Client()
|
305
304
|
model_versions = depaginate(
|
306
|
-
|
305
|
+
client.list_model_versions, model_name_or_id=self.id
|
307
306
|
)
|
308
307
|
return [
|
309
308
|
mv.to_model_class(suppress_class_validation_warnings=True)
|
@@ -493,6 +493,23 @@ class ServiceConnectorResponse(
|
|
493
493
|
max_length=STR_FIELD_MAX_LENGTH,
|
494
494
|
)
|
495
495
|
|
496
|
+
def get_analytics_metadata(self) -> Dict[str, Any]:
|
497
|
+
"""Add the service connector labels to analytics metadata.
|
498
|
+
|
499
|
+
Returns:
|
500
|
+
Dict of analytics metadata.
|
501
|
+
"""
|
502
|
+
metadata = super().get_analytics_metadata()
|
503
|
+
|
504
|
+
metadata.update(
|
505
|
+
{
|
506
|
+
label[6:]: value
|
507
|
+
for label, value in self.labels.items()
|
508
|
+
if label.startswith("zenml:")
|
509
|
+
}
|
510
|
+
)
|
511
|
+
return metadata
|
512
|
+
|
496
513
|
def get_hydrated_version(self) -> "ServiceConnectorResponse":
|
497
514
|
"""Get the hydrated version of this service connector.
|
498
515
|
|
zenml/models/v2/core/stack.py
CHANGED
@@ -36,6 +36,7 @@ from zenml.models.v2.core.component import ComponentResponse
|
|
36
36
|
if TYPE_CHECKING:
|
37
37
|
from sqlalchemy.sql.elements import ColumnElement
|
38
38
|
|
39
|
+
|
39
40
|
# ------------------ Request Model ------------------
|
40
41
|
|
41
42
|
|
@@ -59,6 +60,10 @@ class StackRequest(WorkspaceScopedRequest):
|
|
59
60
|
title="A mapping of stack component types to the actual"
|
60
61
|
"instances of components of this type.",
|
61
62
|
)
|
63
|
+
labels: Optional[Dict[str, Any]] = Field(
|
64
|
+
default=None,
|
65
|
+
title="The stack labels.",
|
66
|
+
)
|
62
67
|
|
63
68
|
@property
|
64
69
|
def is_valid(self) -> bool:
|
@@ -109,6 +114,10 @@ class StackUpdate(BaseUpdate):
|
|
109
114
|
"instances of components of this type.",
|
110
115
|
default=None,
|
111
116
|
)
|
117
|
+
labels: Optional[Dict[str, Any]] = Field(
|
118
|
+
default=None,
|
119
|
+
title="The stack labels.",
|
120
|
+
)
|
112
121
|
|
113
122
|
|
114
123
|
# ------------------ Response Model ------------------
|
@@ -134,6 +143,10 @@ class StackResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
134
143
|
default=None,
|
135
144
|
title="The path to the stack spec used for mlstacks deployments.",
|
136
145
|
)
|
146
|
+
labels: Optional[Dict[str, Any]] = Field(
|
147
|
+
default=None,
|
148
|
+
title="The stack labels.",
|
149
|
+
)
|
137
150
|
|
138
151
|
|
139
152
|
class StackResponseResources(WorkspaceScopedResponseResources):
|
@@ -214,6 +227,15 @@ class StackResponse(
|
|
214
227
|
"""
|
215
228
|
metadata = super().get_analytics_metadata()
|
216
229
|
metadata.update({ct: c[0].flavor for ct, c in self.components.items()})
|
230
|
+
|
231
|
+
if self.labels is not None:
|
232
|
+
metadata.update(
|
233
|
+
{
|
234
|
+
label[6:]: value
|
235
|
+
for label, value in self.labels.items()
|
236
|
+
if label.startswith("zenml:")
|
237
|
+
}
|
238
|
+
)
|
217
239
|
return metadata
|
218
240
|
|
219
241
|
@property
|
@@ -243,6 +265,15 @@ class StackResponse(
|
|
243
265
|
"""
|
244
266
|
return self.get_metadata().components
|
245
267
|
|
268
|
+
@property
|
269
|
+
def labels(self) -> Optional[Dict[str, Any]]:
|
270
|
+
"""The `labels` property.
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
the value of the property.
|
274
|
+
"""
|
275
|
+
return self.get_metadata().labels
|
276
|
+
|
246
277
|
|
247
278
|
# ------------------ Filter Model ------------------
|
248
279
|
|