zenml-nightly 0.63.0.dev20240801__py3-none-any.whl → 0.64.0.dev20240811__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 +2 -2
- RELEASE_NOTES.md +79 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +0 -4
- zenml/analytics/enums.py +0 -6
- zenml/cli/__init__.py +0 -61
- zenml/cli/base.py +1 -1
- zenml/cli/web_login.py +8 -0
- zenml/client.py +0 -4
- zenml/config/build_configuration.py +43 -17
- zenml/config/docker_settings.py +80 -57
- zenml/config/source.py +58 -0
- zenml/constants.py +9 -2
- zenml/entrypoints/base_entrypoint_configuration.py +53 -8
- zenml/enums.py +1 -1
- zenml/environment.py +25 -9
- zenml/image_builders/base_image_builder.py +1 -1
- zenml/image_builders/build_context.py +25 -72
- zenml/integrations/azure/__init__.py +4 -0
- zenml/integrations/azure/flavors/__init__.py +11 -0
- zenml/integrations/azure/flavors/azureml_orchestrator_flavor.py +263 -0
- zenml/{_hub → integrations/azure/orchestrators}/__init__.py +7 -2
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +544 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py +86 -0
- zenml/integrations/azure/step_operators/azureml_step_operator.py +3 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +9 -0
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +7 -2
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +123 -6
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +1 -1
- zenml/integrations/mlflow/__init__.py +1 -1
- zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +3 -1
- zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +3 -0
- zenml/logger.py +13 -0
- zenml/models/__init__.py +0 -12
- zenml/models/v2/core/pipeline_deployment.py +21 -29
- zenml/models/v2/core/pipeline_run.py +13 -0
- zenml/models/v2/core/server_settings.py +12 -0
- zenml/models/v2/core/user.py +0 -21
- zenml/models/v2/misc/server_models.py +7 -1
- zenml/models/v2/misc/user_auth.py +0 -7
- zenml/new/pipelines/build_utils.py +193 -38
- zenml/new/pipelines/code_archive.py +157 -0
- zenml/new/pipelines/pipeline.py +29 -2
- zenml/new/pipelines/run_utils.py +67 -1
- zenml/service_connectors/service_connector_utils.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +26 -3
- zenml/stack_deployments/azure_stack_deployment.py +11 -6
- zenml/stack_deployments/gcp_stack_deployment.py +24 -2
- zenml/stack_deployments/stack_deployment.py +17 -2
- zenml/steps/base_step.py +3 -0
- zenml/utils/archivable.py +149 -0
- zenml/utils/code_utils.py +244 -0
- zenml/utils/notebook_utils.py +122 -0
- zenml/utils/pipeline_docker_image_builder.py +3 -96
- zenml/utils/source_utils.py +109 -1
- zenml/zen_server/dashboard/assets/{404-CI13wQp4.js → 404-CRAA_Lew.js} +1 -1
- zenml/zen_server/dashboard/assets/@radix-BXWm7HOa.js +85 -0
- zenml/zen_server/dashboard/assets/{@react-router-CO-OsFwI.js → @react-router-l3lMcXA2.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-DIYUhKYX.js → @reactflow-CeVxyqYT.js} +2 -2
- zenml/zen_server/dashboard/assets/{@tanstack-k96lU_C-.js → @tanstack-FmcYZMuX.js} +4 -4
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-ErO9aOgK.js +1 -0
- zenml/zen_server/dashboard/assets/{AwarenessChannel-BNg5uWgI.js → AwarenessChannel-CLXo5rKM.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-Cyp7f4dM.js → CodeSnippet-D0VLxT2A.js} +1 -1
- zenml/zen_server/dashboard/assets/{CollapsibleCard-Cu_A9W57.js → CollapsibleCard-BaUPiVg0.js} +1 -1
- zenml/zen_server/dashboard/assets/{Commands-DmQwTXjj.js → Commands-JrcZK-3j.js} +1 -1
- zenml/zen_server/dashboard/assets/CopyButton-Dbo52T1K.js +2 -0
- zenml/zen_server/dashboard/assets/{CsvVizualization-BvqItd-O.js → CsvVizualization-D3kAypDj.js} +3 -3
- zenml/zen_server/dashboard/assets/DisplayDate-DizbSeT-.js +1 -0
- zenml/zen_server/dashboard/assets/EditSecretDialog-Bd7mFLS4.js +1 -0
- zenml/zen_server/dashboard/assets/{EmptyState-BMLnFVlB.js → EmptyState-BHblM39I.js} +1 -1
- zenml/zen_server/dashboard/assets/{Error-DbXCTGua.js → Error-C6LeJSER.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-9zM7eaLh.js → ExecutionStatus-jH4OrWBq.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-BIiNc-uH.js → Helpbox-aAB2XP-z.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-iv1Nu1A0.js → Infobox-BQ0aty32.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-BvBtO2Dp.js → InlineAvatar-DpTLgM3Q.js} +1 -1
- zenml/zen_server/dashboard/assets/Lock-CNyJvf2r.js +1 -0
- zenml/zen_server/dashboard/assets/{MarkdownVisualization-xp3hhULl.js → MarkdownVisualization-Bajxn0HY.js} +1 -1
- zenml/zen_server/dashboard/assets/NumberBox-BmKE0qnO.js +1 -0
- zenml/zen_server/dashboard/assets/{PasswordChecker-DUveqlva.js → PasswordChecker-yGGoJSB-.js} +1 -1
- zenml/zen_server/dashboard/assets/{ProviderRadio-pSAvrGRS.js → ProviderRadio-BBqkIuTd.js} +1 -1
- zenml/zen_server/dashboard/assets/RadioItem-xLhXoiFV.js +1 -0
- zenml/zen_server/dashboard/assets/SearchField-C9R0mdaX.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-BOxpgh6N.js → SetPassword-52sNxNiO.js} +1 -1
- zenml/zen_server/dashboard/assets/{SuccessStep-CTSKN2lp.js → SuccessStep-DlkItqYG.js} +1 -1
- zenml/zen_server/dashboard/assets/{Tick-Bnr2TpW6.js → Tick-uxv80Q6a.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-BeCeaRW5.js → UpdatePasswordSchemas-oN4G3sKz.js} +1 -1
- zenml/zen_server/dashboard/assets/{aws-BgKTfTfx.js → aws-0_3UsPif.js} +1 -1
- zenml/zen_server/dashboard/assets/{check-circle-i56092KI.js → check-circle-1_I207rW.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-down-D_ZlKMqH.js → chevron-down-BpaF8JqM.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-CZBOf6JM.js → chevron-right-double-Dk8e2L99.js} +1 -1
- zenml/zen_server/dashboard/assets/{cloud-only-qelmY92E.js → cloud-only-BkUuI0lZ.js} +1 -1
- zenml/zen_server/dashboard/assets/components-Br2ezRib.js +1 -0
- zenml/zen_server/dashboard/assets/{copy-BXNk6BjL.js → copy-f3XGPPxt.js} +1 -1
- zenml/zen_server/dashboard/assets/{database-1xWSgZfO.js → database-cXYNX9tt.js} +1 -1
- zenml/zen_server/dashboard/assets/{docker-CQMVm_4d.js → docker-8uj__HHK.js} +1 -1
- zenml/zen_server/dashboard/assets/{dots-horizontal-BObFzD5l.js → dots-horizontal-sKQlWEni.js} +1 -1
- zenml/zen_server/dashboard/assets/edit-C0MVvPD2.js +1 -0
- zenml/zen_server/dashboard/assets/{file-text-CqD_iu6l.js → file-text-B9JibxTs.js} +1 -1
- zenml/zen_server/dashboard/assets/{help-bu_DgLKI.js → help-FuHlZwn0.js} +1 -1
- zenml/zen_server/dashboard/assets/index-Bd1xgUQG.js +1 -0
- zenml/zen_server/dashboard/assets/index-DaGknux4.css +1 -0
- zenml/zen_server/dashboard/assets/{index-KsTz2dHG.js → index-DhIZtpxB.js} +5 -5
- zenml/zen_server/dashboard/assets/{index.esm-CbHNSeVw.js → index.esm-DT4uyn2i.js} +1 -1
- zenml/zen_server/dashboard/assets/layout-D6oiSbfd.js +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-DRpbESS7.js → login-mutation-13A_JSVA.js} +1 -1
- zenml/zen_server/dashboard/assets/{logs-D8k8BVFf.js → logs-CgeE2vZP.js} +1 -1
- zenml/zen_server/dashboard/assets/{not-found-Dfx9hfkf.js → not-found-B0Mmb90p.js} +1 -1
- zenml/zen_server/dashboard/assets/{package-ClbU3KUi.js → package-DdkziX79.js} +1 -1
- zenml/zen_server/dashboard/assets/page-7-v2OBm-.js +1 -0
- zenml/zen_server/dashboard/assets/{page-f3jBVI5Z.js → page-B3ozwdD1.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DYBNGxJt.js → page-BGwA9B1M.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-C176KxyB.js → page-BkjAUyTA.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BnacgBiy.js +1 -0
- zenml/zen_server/dashboard/assets/{page-CzucfYPo.js → page-BxF_KMQ3.js} +2 -2
- zenml/zen_server/dashboard/assets/page-C4POHC0K.js +1 -0
- zenml/zen_server/dashboard/assets/page-C9kudd44.js +9 -0
- zenml/zen_server/dashboard/assets/page-CA1j3GpJ.js +1 -0
- zenml/zen_server/dashboard/assets/page-CCY6yfmu.js +1 -0
- zenml/zen_server/dashboard/assets/page-CgTe7Bme.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DtpwnNXq.js → page-Cgn-6v2Y.js} +1 -1
- zenml/zen_server/dashboard/assets/page-CxQmQqDw.js +1 -0
- zenml/zen_server/dashboard/assets/page-D2Goey3H.js +1 -0
- zenml/zen_server/dashboard/assets/page-DLpOnf7u.js +1 -0
- zenml/zen_server/dashboard/assets/{page-DVPxY5fT.js → page-DSTQnBk-.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BoFtUD9H.js → page-DTysUGOy.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-p2hLJdS2.js → page-D_EXUFJb.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Db15QzsM.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Btu39x7k.js → page-DugsjcQ_.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CZe9GEBF.js → page-OFKSPyN7.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CDgZmwxP.js → page-RnG-qhv9.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Cjn97HMv.js → page-T2BtjwPl.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TXe1Eo3Z.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BxiWdeyg.js → page-YiF_fNbe.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-399pVZHU.js → page-hQaiQXfg.js} +1 -1
- zenml/zen_server/dashboard/assets/persist-3-5nOJ6m.js +1 -0
- zenml/zen_server/dashboard/assets/{play-circle-CNtZKDnW.js → play-circle-XSkLR12B.js} +1 -1
- zenml/zen_server/dashboard/assets/{plus-DOeLmm7C.js → plus-FB9-lEq_.js} +1 -1
- zenml/zen_server/dashboard/assets/refresh-COb6KYDi.js +1 -0
- zenml/zen_server/dashboard/assets/sharedSchema-BoYx_B_L.js +14 -0
- zenml/zen_server/dashboard/assets/{stack-detail-query-Ck7j7BP_.js → stack-detail-query-B-US_-wa.js} +1 -1
- zenml/zen_server/dashboard/assets/{terminal-By9cErXc.js → terminal-grtjrIEJ.js} +1 -1
- zenml/zen_server/dashboard/assets/trash-Cd5CSFqA.js +1 -0
- zenml/zen_server/dashboard/assets/{update-server-settings-mutation-f3ZT7psb.js → update-server-settings-mutation-B8GB_ubU.js} +1 -1
- zenml/zen_server/dashboard/assets/{url-rGEp5Umh.js → url-hcMJkz8p.js} +1 -1
- zenml/zen_server/dashboard/assets/{zod-BtSyGx4C.js → zod-CnykDKJj.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.2fa6e528a6e7447caaf35dadfe7514bb.js → precache-manifest.9c473c96a43298343a7ce1256183123b.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/{main.4aab7e98.chunk.js → main.463c90b9.chunk.js} +2 -2
- zenml/zen_server/dashboard_legacy/static/js/{main.4aab7e98.chunk.js.map → main.463c90b9.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/routers/stack_deployment_endpoints.py +6 -0
- zenml/zen_server/routers/users_endpoints.py +0 -7
- zenml/zen_server/utils.py +75 -0
- zenml/zen_server/zen_server_api.py +52 -1
- zenml/zen_stores/base_zen_store.py +7 -1
- zenml/zen_stores/migrations/versions/0.64.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/026d4577b6a0_add_code_path.py +39 -0
- zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +51 -0
- zenml/zen_stores/migrations/versions/909550c7c4da_remove_user_hub_token.py +36 -0
- zenml/zen_stores/rest_zen_store.py +5 -3
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +3 -0
- zenml/zen_stores/schemas/pipeline_run_schemas.py +3 -0
- zenml/zen_stores/schemas/server_settings_schemas.py +2 -0
- zenml/zen_stores/schemas/user_schemas.py +0 -2
- zenml/zen_stores/sql_zen_store.py +25 -1
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240811.dist-info}/METADATA +3 -3
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240811.dist-info}/RECORD +174 -157
- zenml/_hub/client.py +0 -289
- zenml/_hub/constants.py +0 -21
- zenml/_hub/utils.py +0 -79
- zenml/cli/hub.py +0 -1116
- zenml/models/v2/misc/hub_plugin_models.py +0 -79
- zenml/zen_server/dashboard/assets/@radix-CFOkMR_E.js +0 -85
- zenml/zen_server/dashboard/assets/CopyButton-B3sWVJ4Z.js +0 -2
- zenml/zen_server/dashboard/assets/DisplayDate-DYgIjlDF.js +0 -1
- zenml/zen_server/dashboard/assets/SearchField-CXoBknpt.js +0 -1
- zenml/zen_server/dashboard/assets/components-DWe4cTjS.js +0 -1
- zenml/zen_server/dashboard/assets/index-vfjX_fJV.css +0 -1
- zenml/zen_server/dashboard/assets/page-C6tXXjnK.js +0 -1
- zenml/zen_server/dashboard/assets/page-CP9obrnG.js +0 -1
- zenml/zen_server/dashboard/assets/page-CaTOsNNw.js +0 -1
- zenml/zen_server/dashboard/assets/page-CmXmB_5i.js +0 -1
- zenml/zen_server/dashboard/assets/page-CvGAOfad.js +0 -1
- zenml/zen_server/dashboard/assets/page-D0bbc-qr.js +0 -5
- zenml/zen_server/dashboard/assets/page-DLEtD2ex.js +0 -1
- zenml/zen_server/dashboard/assets/page-DupV0aBd.js +0 -1
- zenml/zen_server/dashboard/assets/page-EweAR81y.js +0 -1
- zenml/zen_server/dashboard/assets/page-w-YaL77M.js +0 -9
- zenml/zen_server/dashboard/assets/persist-BReKApOc.js +0 -14
- zenml/zen_server/dashboard/assets/secrets-video-OBJ6irhH.svg +0 -21
- zenml/zen_server/dashboard/assets/stacks-video-7gfxpAq4.svg +0 -21
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240811.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240811.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240811.dist-info}/entry_points.txt +0 -0
zenml/config/source.py
CHANGED
@@ -42,6 +42,7 @@ class SourceType(Enum):
|
|
42
42
|
INTERNAL = "internal"
|
43
43
|
DISTRIBUTION_PACKAGE = "distribution_package"
|
44
44
|
CODE_REPOSITORY = "code_repository"
|
45
|
+
NOTEBOOK = "notebook"
|
45
46
|
UNKNOWN = "unknown"
|
46
47
|
|
47
48
|
|
@@ -229,6 +230,63 @@ class CodeRepositorySource(Source):
|
|
229
230
|
return value
|
230
231
|
|
231
232
|
|
233
|
+
class NotebookSource(Source):
|
234
|
+
"""Source representing an object defined in a notebook.
|
235
|
+
|
236
|
+
Attributes:
|
237
|
+
code_path: Path where the notebook cell code for this source is
|
238
|
+
uploaded.
|
239
|
+
replacement_module: Name of the module from which this source should
|
240
|
+
be loaded in case the code is not running in a notebook.
|
241
|
+
"""
|
242
|
+
|
243
|
+
code_path: Optional[str] = None
|
244
|
+
replacement_module: Optional[str] = None
|
245
|
+
type: SourceType = SourceType.NOTEBOOK
|
246
|
+
|
247
|
+
# Private attribute that is used to store the code but should not be
|
248
|
+
# serialized
|
249
|
+
_cell_code: Optional[str] = None
|
250
|
+
|
251
|
+
@field_validator("type")
|
252
|
+
@classmethod
|
253
|
+
def _validate_type(cls, value: SourceType) -> SourceType:
|
254
|
+
"""Validate the source type.
|
255
|
+
|
256
|
+
Args:
|
257
|
+
value: The source type.
|
258
|
+
|
259
|
+
Raises:
|
260
|
+
ValueError: If the source type is not `NOTEBOOK`.
|
261
|
+
|
262
|
+
Returns:
|
263
|
+
The source type.
|
264
|
+
"""
|
265
|
+
if value != SourceType.NOTEBOOK:
|
266
|
+
raise ValueError("Invalid source type.")
|
267
|
+
|
268
|
+
return value
|
269
|
+
|
270
|
+
@field_validator("module")
|
271
|
+
@classmethod
|
272
|
+
def _validate_module(cls, value: str) -> str:
|
273
|
+
"""Validate the module.
|
274
|
+
|
275
|
+
Args:
|
276
|
+
value: The module.
|
277
|
+
|
278
|
+
Raises:
|
279
|
+
ValueError: If the module is not `__main__`.
|
280
|
+
|
281
|
+
Returns:
|
282
|
+
The module.
|
283
|
+
"""
|
284
|
+
if value != "__main__":
|
285
|
+
raise ValueError("Invalid module for notebook source.")
|
286
|
+
|
287
|
+
return value
|
288
|
+
|
289
|
+
|
232
290
|
def convert_source(source: Any) -> Any:
|
233
291
|
"""Converts an old source string to a source object.
|
234
292
|
|
zenml/constants.py
CHANGED
@@ -165,7 +165,6 @@ ENV_ZENML_SKIP_IMAGE_BUILDER_DEFAULT = "ZENML_SKIP_IMAGE_BUILDER_DEFAULT"
|
|
165
165
|
ENV_ZENML_REQUIRES_CODE_DOWNLOAD = "ZENML_REQUIRES_CODE_DOWNLOAD"
|
166
166
|
ENV_ZENML_SERVER = "ZENML_SERVER"
|
167
167
|
ENV_ZENML_LOCAL_SERVER = "ZENML_LOCAL_SERVER"
|
168
|
-
ENV_ZENML_HUB_URL = "ZENML_HUB_URL"
|
169
168
|
ENV_ZENML_ENFORCE_TYPE_ANNOTATIONS = "ZENML_ENFORCE_TYPE_ANNOTATIONS"
|
170
169
|
ENV_ZENML_ENABLE_IMPLICIT_AUTH_METHODS = "ZENML_ENABLE_IMPLICIT_AUTH_METHODS"
|
171
170
|
ENV_ZENML_DISABLE_STEP_LOGS_STORAGE = "ZENML_DISABLE_STEP_LOGS_STORAGE"
|
@@ -279,7 +278,6 @@ DEFAULT_ZENML_SERVER_SECURE_HEADERS_CONTENT = "nosniff"
|
|
279
278
|
_csp_script_src_urls = ["https://widgets-v3.featureos.app"]
|
280
279
|
_csp_connect_src_urls = [
|
281
280
|
"https://sdkdocs.zenml.io",
|
282
|
-
"https://hubapi.zenml.io",
|
283
281
|
"https://analytics.zenml.io",
|
284
282
|
]
|
285
283
|
_csp_img_src_urls = [
|
@@ -315,6 +313,7 @@ DEFAULT_ZENML_SERVER_SECURE_HEADERS_PERMISSIONS = (
|
|
315
313
|
)
|
316
314
|
DEFAULT_ZENML_SERVER_SECURE_HEADERS_REPORT_TO = "default"
|
317
315
|
DEFAULT_ZENML_SERVER_USE_LEGACY_DASHBOARD = False
|
316
|
+
DEFAULT_ZENML_SERVER_REPORT_USER_ACTIVITY_TO_DB_SECONDS = 30
|
318
317
|
|
319
318
|
# Configurations to decide which resources report their usage and check for
|
320
319
|
# entitlement in the case of a cloud deployment. Expected Format is this:
|
@@ -494,3 +493,11 @@ BANNED_NAME_CHARACTERS = "\t\n\r\v\f"
|
|
494
493
|
|
495
494
|
|
496
495
|
STACK_DEPLOYMENT_API_TOKEN_EXPIRATION = 60 * 6 # 6 hours
|
496
|
+
|
497
|
+
# ZenML Pro
|
498
|
+
ZENML_PRO_CONNECTION_ISSUES_SUSPENDED_PAUSED_TENANT_HINT = (
|
499
|
+
"\nHINT: Since you are trying to communicate with the ZenML Pro Tenant, "
|
500
|
+
"please make sure that your tenant is in RUNNING state on your "
|
501
|
+
"Organization page. If the tenant is PAUSED you can `Resume` it via UI "
|
502
|
+
"and try again."
|
503
|
+
)
|
@@ -27,10 +27,15 @@ from zenml.constants import (
|
|
27
27
|
handle_bool_env_var,
|
28
28
|
)
|
29
29
|
from zenml.logger import get_logger
|
30
|
-
from zenml.utils import
|
30
|
+
from zenml.utils import (
|
31
|
+
code_repository_utils,
|
32
|
+
code_utils,
|
33
|
+
source_utils,
|
34
|
+
uuid_utils,
|
35
|
+
)
|
31
36
|
|
32
37
|
if TYPE_CHECKING:
|
33
|
-
from zenml.models import PipelineDeploymentResponse
|
38
|
+
from zenml.models import CodeReferenceResponse, PipelineDeploymentResponse
|
34
39
|
|
35
40
|
logger = get_logger(__name__)
|
36
41
|
DEFAULT_ENTRYPOINT_COMMAND = [
|
@@ -198,7 +203,7 @@ class BaseEntrypointConfiguration(ABC):
|
|
198
203
|
|
199
204
|
Raises:
|
200
205
|
RuntimeError: If the current environment requires code download
|
201
|
-
but the deployment does not have
|
206
|
+
but the deployment does not have a reference to any code.
|
202
207
|
"""
|
203
208
|
requires_code_download = handle_bool_env_var(
|
204
209
|
ENV_ZENML_REQUIRES_CODE_DOWNLOAD
|
@@ -207,17 +212,33 @@ class BaseEntrypointConfiguration(ABC):
|
|
207
212
|
if not requires_code_download:
|
208
213
|
return
|
209
214
|
|
210
|
-
code_reference
|
211
|
-
|
215
|
+
if code_reference := deployment.code_reference:
|
216
|
+
self.download_code_from_code_repository(
|
217
|
+
code_reference=code_reference
|
218
|
+
)
|
219
|
+
elif code_path := deployment.code_path:
|
220
|
+
self.download_code_from_artifact_store(code_path=code_path)
|
221
|
+
else:
|
212
222
|
raise RuntimeError(
|
213
|
-
"Code download required but no code reference provided."
|
223
|
+
"Code download required but no code reference or path provided."
|
214
224
|
)
|
215
225
|
|
226
|
+
logger.info("Code download finished.")
|
227
|
+
|
228
|
+
def download_code_from_code_repository(
|
229
|
+
self, code_reference: "CodeReferenceResponse"
|
230
|
+
) -> None:
|
231
|
+
"""Download code from a code repository.
|
232
|
+
|
233
|
+
Args:
|
234
|
+
code_reference: The reference to the code.
|
235
|
+
"""
|
216
236
|
logger.info(
|
217
237
|
"Downloading code from code repository `%s` (commit `%s`).",
|
218
238
|
code_reference.code_repository.name,
|
219
239
|
code_reference.commit,
|
220
240
|
)
|
241
|
+
|
221
242
|
model = Client().get_code_repository(code_reference.code_repository.id)
|
222
243
|
repo = BaseCodeRepository.from_model(model)
|
223
244
|
code_repo_root = os.path.abspath("code")
|
@@ -234,10 +255,34 @@ class BaseEntrypointConfiguration(ABC):
|
|
234
255
|
code_repository_utils.set_custom_local_repository(
|
235
256
|
root=code_repo_root, commit=code_reference.commit, repo=repo
|
236
257
|
)
|
237
|
-
|
258
|
+
|
238
259
|
sys.path.insert(0, download_dir)
|
260
|
+
os.chdir(download_dir)
|
239
261
|
|
240
|
-
|
262
|
+
def download_code_from_artifact_store(self, code_path: str) -> None:
|
263
|
+
"""Download code from the artifact store.
|
264
|
+
|
265
|
+
Args:
|
266
|
+
code_path: Path where the code is stored.
|
267
|
+
"""
|
268
|
+
logger.info(
|
269
|
+
"Downloading code from artifact store path `%s`.", code_path
|
270
|
+
)
|
271
|
+
|
272
|
+
# Do not remove this line, we need to instantiate the artifact store to
|
273
|
+
# register the filesystem needed for the file download
|
274
|
+
_ = Client().active_stack.artifact_store
|
275
|
+
|
276
|
+
extract_dir = os.path.abspath("code")
|
277
|
+
os.makedirs(extract_dir)
|
278
|
+
|
279
|
+
code_utils.download_and_extract_code(
|
280
|
+
code_path=code_path, extract_dir=extract_dir
|
281
|
+
)
|
282
|
+
|
283
|
+
source_utils.set_custom_source_root(extract_dir)
|
284
|
+
sys.path.insert(0, extract_dir)
|
285
|
+
os.chdir(extract_dir)
|
241
286
|
|
242
287
|
@abstractmethod
|
243
288
|
def run(self) -> None:
|
zenml/enums.py
CHANGED
@@ -171,7 +171,6 @@ class CliCategories(StrEnum):
|
|
171
171
|
|
172
172
|
STACK_COMPONENTS = "Stack Components"
|
173
173
|
MODEL_DEPLOYMENT = "Model Deployment"
|
174
|
-
HUB = "ZenML Hub"
|
175
174
|
INTEGRATIONS = "Integrations"
|
176
175
|
MANAGEMENT_TOOLS = "Management Tools"
|
177
176
|
MODEL_CONTROL_PLANE = "Model Control Plane"
|
@@ -303,6 +302,7 @@ class EnvironmentType(StrEnum):
|
|
303
302
|
NOTEBOOK = "notebook"
|
304
303
|
PAPERSPACE = "paperspace"
|
305
304
|
WSL = "wsl"
|
305
|
+
LIGHTNING_AI_STUDIO = "lightning_ai_studio"
|
306
306
|
|
307
307
|
|
308
308
|
class ModelStages(StrEnum):
|
zenml/environment.py
CHANGED
@@ -15,7 +15,6 @@
|
|
15
15
|
|
16
16
|
import os
|
17
17
|
import platform
|
18
|
-
from importlib.util import find_spec
|
19
18
|
from pathlib import Path
|
20
19
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Type, cast
|
21
20
|
|
@@ -70,6 +69,8 @@ def get_environment() -> str:
|
|
70
69
|
return EnvironmentType.BITBUCKET_CI
|
71
70
|
elif Environment.in_ci():
|
72
71
|
return EnvironmentType.GENERIC_CI
|
72
|
+
elif Environment.in_lightning_ai_studio():
|
73
|
+
return EnvironmentType.LIGHTNING_AI_STUDIO
|
73
74
|
elif Environment.in_docker():
|
74
75
|
return EnvironmentType.DOCKER
|
75
76
|
elif Environment.in_container():
|
@@ -257,15 +258,17 @@ class Environment(metaclass=SingletonMetaClass):
|
|
257
258
|
if Environment.in_google_colab():
|
258
259
|
return True
|
259
260
|
|
260
|
-
|
261
|
-
|
261
|
+
try:
|
262
|
+
ipython = get_ipython() # type: ignore[name-defined]
|
263
|
+
except NameError:
|
264
|
+
return False
|
262
265
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
266
|
+
if ipython.__class__.__name__ in [
|
267
|
+
"TerminalInteractiveShell",
|
268
|
+
"ZMQInteractiveShell",
|
269
|
+
"DatabricksShell",
|
270
|
+
]:
|
271
|
+
return True
|
269
272
|
return False
|
270
273
|
|
271
274
|
@staticmethod
|
@@ -339,6 +342,19 @@ class Environment(metaclass=SingletonMetaClass):
|
|
339
342
|
"""
|
340
343
|
return "microsoft-standard" in platform.uname().release
|
341
344
|
|
345
|
+
@staticmethod
|
346
|
+
def in_lightning_ai_studio() -> bool:
|
347
|
+
"""If the current Python process is running in Lightning.ai studios.
|
348
|
+
|
349
|
+
Returns:
|
350
|
+
`True` if the current Python process is running in Lightning.ai studios,
|
351
|
+
`False` otherwise.
|
352
|
+
"""
|
353
|
+
return (
|
354
|
+
"LIGHTNING_CLOUD_URL" in os.environ
|
355
|
+
and "LIGHTNING_CLOUDSPACE_HOST" in os.environ
|
356
|
+
)
|
357
|
+
|
342
358
|
def register_component(
|
343
359
|
self, component: "BaseEnvironmentComponent"
|
344
360
|
) -> "BaseEnvironmentComponent":
|
@@ -119,7 +119,7 @@ class BaseImageBuilder(StackComponent, ABC):
|
|
119
119
|
|
120
120
|
hash_ = hashlib.sha1() # nosec
|
121
121
|
with tempfile.NamedTemporaryFile(mode="w+b", delete=False) as f:
|
122
|
-
build_context.write_archive(f,
|
122
|
+
build_context.write_archive(f, use_gzip=True)
|
123
123
|
|
124
124
|
while True:
|
125
125
|
data = f.read(64 * 1024)
|
@@ -14,18 +14,18 @@
|
|
14
14
|
"""Image build context."""
|
15
15
|
|
16
16
|
import os
|
17
|
-
from
|
18
|
-
from typing import IO, Dict, List, Optional, Set, Tuple, cast
|
17
|
+
from typing import IO, Dict, List, Optional, Set, cast
|
19
18
|
|
20
19
|
from zenml.constants import REPOSITORY_DIRECTORY_NAME
|
21
20
|
from zenml.io import fileio
|
22
21
|
from zenml.logger import get_logger
|
23
22
|
from zenml.utils import io_utils, string_utils
|
23
|
+
from zenml.utils.archivable import Archivable
|
24
24
|
|
25
25
|
logger = get_logger(__name__)
|
26
26
|
|
27
27
|
|
28
|
-
class BuildContext:
|
28
|
+
class BuildContext(Archivable):
|
29
29
|
"""Image build context.
|
30
30
|
|
31
31
|
This class is responsible for creating an archive of the files needed to
|
@@ -45,9 +45,9 @@ class BuildContext:
|
|
45
45
|
given, a file called `.dockerignore` in the build context root
|
46
46
|
directory will be used instead if it exists.
|
47
47
|
"""
|
48
|
+
super().__init__()
|
48
49
|
self._root = root
|
49
50
|
self._dockerignore_file = dockerignore_file
|
50
|
-
self._extra_files: Dict[str, str] = {}
|
51
51
|
|
52
52
|
@property
|
53
53
|
def dockerignore_file(self) -> Optional[str]:
|
@@ -68,70 +68,26 @@ class BuildContext:
|
|
68
68
|
|
69
69
|
return None
|
70
70
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
Args:
|
75
|
-
source: The source of the file to add. This can either be a path
|
76
|
-
or the file content.
|
77
|
-
destination: The path inside the build context where the file
|
78
|
-
should be added.
|
79
|
-
"""
|
80
|
-
if fileio.exists(source):
|
81
|
-
with fileio.open(source) as f:
|
82
|
-
self._extra_files[destination] = f.read()
|
83
|
-
else:
|
84
|
-
self._extra_files[destination] = source
|
85
|
-
|
86
|
-
def add_directory(self, source: str, destination: str) -> None:
|
87
|
-
"""Adds a directory to the build context.
|
88
|
-
|
89
|
-
Args:
|
90
|
-
source: Path to the directory.
|
91
|
-
destination: The path inside the build context where the directory
|
92
|
-
should be added.
|
93
|
-
|
94
|
-
Raises:
|
95
|
-
ValueError: If `source` does not point to a directory.
|
96
|
-
"""
|
97
|
-
if not fileio.isdir(source):
|
98
|
-
raise ValueError(
|
99
|
-
f"Can't add directory {source} to the build context as it "
|
100
|
-
"does not exist or is not a directory."
|
101
|
-
)
|
102
|
-
|
103
|
-
for dir, _, files in fileio.walk(source):
|
104
|
-
dir_path = Path(fileio.convert_to_str(dir))
|
105
|
-
for file_name in files:
|
106
|
-
file_name = fileio.convert_to_str(file_name)
|
107
|
-
file_source = dir_path / file_name
|
108
|
-
file_destination = (
|
109
|
-
Path(destination)
|
110
|
-
/ dir_path.relative_to(source)
|
111
|
-
/ file_name
|
112
|
-
)
|
113
|
-
|
114
|
-
with file_source.open("r") as f:
|
115
|
-
self._extra_files[file_destination.as_posix()] = f.read()
|
116
|
-
|
117
|
-
def write_archive(self, output_file: IO[bytes], gzip: bool = True) -> None:
|
71
|
+
def write_archive(
|
72
|
+
self, output_file: IO[bytes], use_gzip: bool = True
|
73
|
+
) -> None:
|
118
74
|
"""Writes an archive of the build context to the given file.
|
119
75
|
|
120
76
|
Args:
|
121
77
|
output_file: The file to write the archive to.
|
122
|
-
|
78
|
+
use_gzip: Whether to use `gzip` to compress the file.
|
123
79
|
"""
|
124
80
|
from docker.utils import build as docker_build_utils
|
125
81
|
|
126
|
-
files = self.
|
127
|
-
extra_files = self.
|
82
|
+
files = self.get_files()
|
83
|
+
extra_files = self.get_extra_files()
|
128
84
|
|
129
85
|
context_archive = docker_build_utils.create_archive(
|
130
86
|
fileobj=output_file,
|
131
87
|
root=self._root,
|
132
|
-
files=sorted(files),
|
133
|
-
gzip=
|
134
|
-
extra_files=extra_files,
|
88
|
+
files=sorted(files.keys()),
|
89
|
+
gzip=use_gzip,
|
90
|
+
extra_files=list(extra_files.items()),
|
135
91
|
)
|
136
92
|
|
137
93
|
build_context_size = os.path.getsize(context_archive.name)
|
@@ -151,33 +107,30 @@ class BuildContext:
|
|
151
107
|
os.path.join(self._root, ".dockerignore"),
|
152
108
|
)
|
153
109
|
|
154
|
-
def
|
155
|
-
"""Gets all
|
110
|
+
def get_files(self) -> Dict[str, str]:
|
111
|
+
"""Gets all regular files that should be included in the archive.
|
156
112
|
|
157
113
|
Returns:
|
158
|
-
|
114
|
+
A dict {path_in_archive: path_on_filesystem} for all regular files
|
115
|
+
in the archive.
|
159
116
|
"""
|
160
117
|
if self._root:
|
161
|
-
exclude_patterns = self._get_exclude_patterns()
|
162
118
|
from docker.utils import build as docker_build_utils
|
163
119
|
|
164
|
-
|
120
|
+
exclude_patterns = self._get_exclude_patterns()
|
121
|
+
|
122
|
+
archive_paths = cast(
|
165
123
|
Set[str],
|
166
124
|
docker_build_utils.exclude_paths(
|
167
125
|
self._root, patterns=exclude_patterns
|
168
126
|
),
|
169
127
|
)
|
128
|
+
return {
|
129
|
+
archive_path: os.path.join(self._root, archive_path)
|
130
|
+
for archive_path in archive_paths
|
131
|
+
}
|
170
132
|
else:
|
171
|
-
return
|
172
|
-
|
173
|
-
def _get_extra_files(self) -> List[Tuple[str, str]]:
|
174
|
-
"""Gets all extra files of the build context.
|
175
|
-
|
176
|
-
Returns:
|
177
|
-
A tuple (path, file_content) for all extra files in the build
|
178
|
-
context.
|
179
|
-
"""
|
180
|
-
return list(self._extra_files.items())
|
133
|
+
return {}
|
181
134
|
|
182
135
|
def _get_exclude_patterns(self) -> List[str]:
|
183
136
|
"""Gets all exclude patterns from the dockerignore file.
|
@@ -27,6 +27,7 @@ from zenml.stack import Flavor
|
|
27
27
|
|
28
28
|
AZURE_ARTIFACT_STORE_FLAVOR = "azure"
|
29
29
|
AZUREML_STEP_OPERATOR_FLAVOR = "azureml"
|
30
|
+
AZUREML_ORCHESTRATOR_FLAVOR = "azureml"
|
30
31
|
|
31
32
|
# Service connector constants
|
32
33
|
AZURE_CONNECTOR_TYPE = "azure"
|
@@ -47,6 +48,7 @@ class AzureIntegration(Integration):
|
|
47
48
|
"azure-mgmt-containerservice>=20.0.0",
|
48
49
|
"azure-storage-blob==12.17.0", # temporary fix for https://github.com/Azure/azure-sdk-for-python/issues/32056
|
49
50
|
"kubernetes",
|
51
|
+
"azure-ai-ml==1.18.0"
|
50
52
|
]
|
51
53
|
REQUIREMENTS_IGNORED_ON_UNINSTALL = ["kubernetes"]
|
52
54
|
|
@@ -65,11 +67,13 @@ class AzureIntegration(Integration):
|
|
65
67
|
from zenml.integrations.azure.flavors import (
|
66
68
|
AzureArtifactStoreFlavor,
|
67
69
|
AzureMLStepOperatorFlavor,
|
70
|
+
AzureMLOrchestratorFlavor,
|
68
71
|
)
|
69
72
|
|
70
73
|
return [
|
71
74
|
AzureArtifactStoreFlavor,
|
72
75
|
AzureMLStepOperatorFlavor,
|
76
|
+
AzureMLOrchestratorFlavor,
|
73
77
|
]
|
74
78
|
|
75
79
|
|
@@ -16,10 +16,17 @@
|
|
16
16
|
from zenml.integrations.azure.flavors.azure_artifact_store_flavor import (
|
17
17
|
AzureArtifactStoreConfig,
|
18
18
|
AzureArtifactStoreFlavor,
|
19
|
+
|
19
20
|
)
|
20
21
|
from zenml.integrations.azure.flavors.azureml_step_operator_flavor import (
|
21
22
|
AzureMLStepOperatorConfig,
|
22
23
|
AzureMLStepOperatorFlavor,
|
24
|
+
AzureMLStepOperatorSettings,
|
25
|
+
)
|
26
|
+
from zenml.integrations.azure.flavors.azureml_orchestrator_flavor import (
|
27
|
+
AzureMLOrchestratorConfig,
|
28
|
+
AzureMLOrchestratorFlavor,
|
29
|
+
AzureMLOrchestratorSettings,
|
23
30
|
)
|
24
31
|
|
25
32
|
__all__ = [
|
@@ -27,4 +34,8 @@ __all__ = [
|
|
27
34
|
"AzureArtifactStoreConfig",
|
28
35
|
"AzureMLStepOperatorFlavor",
|
29
36
|
"AzureMLStepOperatorConfig",
|
37
|
+
"AzureMLStepOperatorSettings",
|
38
|
+
"AzureMLOrchestratorFlavor",
|
39
|
+
"AzureMLOrchestratorConfig",
|
40
|
+
"AzureMLOrchestratorSettings",
|
30
41
|
]
|