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
@@ -0,0 +1,122 @@
|
|
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
|
+
"""Notebook utilities."""
|
15
|
+
|
16
|
+
from typing import Any, Callable, Optional, TypeVar, Union
|
17
|
+
|
18
|
+
from zenml.environment import Environment
|
19
|
+
from zenml.logger import get_logger
|
20
|
+
|
21
|
+
ZENML_NOTEBOOK_CELL_CODE_ATTRIBUTE_NAME = "__zenml_notebook_cell_code__"
|
22
|
+
|
23
|
+
AnyObject = TypeVar("AnyObject", bound=Any)
|
24
|
+
|
25
|
+
logger = get_logger(__name__)
|
26
|
+
|
27
|
+
|
28
|
+
def is_defined_in_notebook_cell(obj: Any) -> bool:
|
29
|
+
"""Check whether an object is defined in a notebook cell.
|
30
|
+
|
31
|
+
Args:
|
32
|
+
obj: The object to check.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
Whether the object is defined in a notebook cell.
|
36
|
+
"""
|
37
|
+
if not Environment.in_notebook():
|
38
|
+
return False
|
39
|
+
|
40
|
+
module_name = getattr(obj, "__module__", None)
|
41
|
+
return module_name == "__main__"
|
42
|
+
|
43
|
+
|
44
|
+
def enable_notebook_code_extraction(
|
45
|
+
_obj: Optional["AnyObject"] = None,
|
46
|
+
) -> Union["AnyObject", Callable[["AnyObject"], "AnyObject"]]:
|
47
|
+
"""Decorator to enable code extraction from notebooks.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
_obj: The class or function for which to enable code extraction.
|
51
|
+
|
52
|
+
Returns:
|
53
|
+
The decorated class or function.
|
54
|
+
"""
|
55
|
+
|
56
|
+
def inner_decorator(obj: "AnyObject") -> "AnyObject":
|
57
|
+
try_to_save_notebook_cell_code(obj)
|
58
|
+
return obj
|
59
|
+
|
60
|
+
if _obj is None:
|
61
|
+
return inner_decorator
|
62
|
+
else:
|
63
|
+
return inner_decorator(_obj)
|
64
|
+
|
65
|
+
|
66
|
+
def get_active_notebook_cell_code() -> Optional[str]:
|
67
|
+
"""Get the code of the currently active notebook cell.
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
The code of the currently active notebook cell.
|
71
|
+
"""
|
72
|
+
cell_code = None
|
73
|
+
try:
|
74
|
+
ipython = get_ipython() # type: ignore[name-defined]
|
75
|
+
cell_code = ipython.get_parent()["content"]["code"]
|
76
|
+
except (NameError, KeyError) as e:
|
77
|
+
logger.warning("Unable to extract cell code: %s.", str(e))
|
78
|
+
|
79
|
+
return cell_code
|
80
|
+
|
81
|
+
|
82
|
+
def try_to_save_notebook_cell_code(obj: Any) -> None:
|
83
|
+
"""Try to save the notebook cell code for an object.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
obj: The object for which to save the notebook cell code.
|
87
|
+
"""
|
88
|
+
if is_defined_in_notebook_cell(obj):
|
89
|
+
if cell_code := get_active_notebook_cell_code():
|
90
|
+
setattr(
|
91
|
+
obj,
|
92
|
+
ZENML_NOTEBOOK_CELL_CODE_ATTRIBUTE_NAME,
|
93
|
+
cell_code,
|
94
|
+
)
|
95
|
+
|
96
|
+
|
97
|
+
def load_notebook_cell_code(obj: Any) -> Optional[str]:
|
98
|
+
"""Load the notebook cell code for an object.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
obj: The object for which to load the cell code.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
The notebook cell code if it was saved.
|
105
|
+
"""
|
106
|
+
return getattr(obj, ZENML_NOTEBOOK_CELL_CODE_ATTRIBUTE_NAME, None)
|
107
|
+
|
108
|
+
|
109
|
+
def warn_about_notebook_cell_magic_commands(cell_code: str) -> None:
|
110
|
+
"""Warn about magic commands in the cell code.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
cell_code: The cell code.
|
114
|
+
"""
|
115
|
+
if any(line.startswith(("%", "!")) for line in cell_code.splitlines()):
|
116
|
+
logger.warning(
|
117
|
+
"Some lines in your notebook cell start with a `!` or `%` "
|
118
|
+
"character. Running a ZenML step remotely from a notebook "
|
119
|
+
"only works if the cell only contains python code. If any "
|
120
|
+
"of these lines contain Jupyter notebook magic commands, "
|
121
|
+
"remove them and try again."
|
122
|
+
)
|
@@ -17,11 +17,9 @@ import itertools
|
|
17
17
|
import os
|
18
18
|
import subprocess
|
19
19
|
import sys
|
20
|
-
from collections import defaultdict
|
21
20
|
from typing import (
|
22
21
|
TYPE_CHECKING,
|
23
22
|
Any,
|
24
|
-
DefaultDict,
|
25
23
|
Dict,
|
26
24
|
List,
|
27
25
|
Optional,
|
@@ -277,9 +275,7 @@ class PipelineDockerImageBuilder:
|
|
277
275
|
requirements_files = self.gather_requirements_files(
|
278
276
|
docker_settings=docker_settings,
|
279
277
|
stack=stack,
|
280
|
-
|
281
|
-
# need to download code
|
282
|
-
code_repository=code_repository if download_files else None,
|
278
|
+
code_repository=code_repository,
|
283
279
|
)
|
284
280
|
|
285
281
|
self._add_requirements_files(
|
@@ -444,8 +440,9 @@ class PipelineDockerImageBuilder:
|
|
444
440
|
requirements files.
|
445
441
|
The files will be in the following order:
|
446
442
|
- Packages installed in the local Python environment
|
443
|
+
- Requirements defined by stack integrations
|
444
|
+
- Requirements defined by user integrations
|
447
445
|
- User-defined requirements
|
448
|
-
- Requirements defined by user-defined and/or stack integrations
|
449
446
|
"""
|
450
447
|
requirements_files: List[Tuple[str, str, List[str]]] = []
|
451
448
|
|
@@ -481,43 +478,6 @@ class PipelineDockerImageBuilder:
|
|
481
478
|
"- Including python packages from local environment"
|
482
479
|
)
|
483
480
|
|
484
|
-
# Generate requirements files for all ZenML Hub plugins
|
485
|
-
if docker_settings.required_hub_plugins:
|
486
|
-
(
|
487
|
-
hub_internal_requirements,
|
488
|
-
hub_pypi_requirements,
|
489
|
-
) = PipelineDockerImageBuilder._get_hub_requirements(
|
490
|
-
docker_settings.required_hub_plugins
|
491
|
-
)
|
492
|
-
|
493
|
-
# Plugin packages themselves
|
494
|
-
for i, (index, packages) in enumerate(
|
495
|
-
hub_internal_requirements.items()
|
496
|
-
):
|
497
|
-
file_name = f".zenml_hub_internal_requirements_{i}"
|
498
|
-
file_lines = [f"-i {index}", *packages]
|
499
|
-
file_contents = "\n".join(file_lines)
|
500
|
-
requirements_files.append(
|
501
|
-
(file_name, file_contents, ["--no-deps"])
|
502
|
-
)
|
503
|
-
if log:
|
504
|
-
logger.info(
|
505
|
-
"- Including internal hub packages from index `%s`: %s",
|
506
|
-
index,
|
507
|
-
", ".join(f"`{r}`" for r in packages),
|
508
|
-
)
|
509
|
-
|
510
|
-
# PyPI requirements of plugin packages
|
511
|
-
if hub_pypi_requirements:
|
512
|
-
file_name = ".zenml_hub_pypi_requirements"
|
513
|
-
file_contents = "\n".join(hub_pypi_requirements)
|
514
|
-
requirements_files.append((file_name, file_contents, []))
|
515
|
-
if log:
|
516
|
-
logger.info(
|
517
|
-
"- Including hub requirements from PyPI: %s",
|
518
|
-
", ".join(f"`{r}`" for r in hub_pypi_requirements),
|
519
|
-
)
|
520
|
-
|
521
481
|
if docker_settings.install_stack_requirements:
|
522
482
|
stack_requirements = stack.requirements()
|
523
483
|
if code_repository:
|
@@ -599,59 +559,6 @@ class PipelineDockerImageBuilder:
|
|
599
559
|
|
600
560
|
return requirements_files
|
601
561
|
|
602
|
-
@staticmethod
|
603
|
-
def _get_hub_requirements(
|
604
|
-
required_hub_plugins: List[str],
|
605
|
-
) -> Tuple[Dict[str, List[str]], List[str]]:
|
606
|
-
"""Get package requirements for ZenML Hub plugins.
|
607
|
-
|
608
|
-
Args:
|
609
|
-
required_hub_plugins: List of hub plugin names in the format
|
610
|
-
`(<author_username>/)<plugin_name>(==<version>)`.
|
611
|
-
|
612
|
-
Returns:
|
613
|
-
- A dict of the hub plugin packages themselves (which need to be
|
614
|
-
installed from a custom index, mapping index URLs to lists of
|
615
|
-
package names.
|
616
|
-
- A list of all unique dependencies of the required hub plugins
|
617
|
-
(which can be installed from PyPI).
|
618
|
-
"""
|
619
|
-
from zenml._hub.client import HubClient
|
620
|
-
from zenml._hub.utils import parse_plugin_name, plugin_display_name
|
621
|
-
|
622
|
-
client = HubClient()
|
623
|
-
|
624
|
-
internal_requirements: DefaultDict[str, List[str]] = defaultdict(list)
|
625
|
-
pypi_requirements: List[str] = []
|
626
|
-
|
627
|
-
for plugin_str in required_hub_plugins:
|
628
|
-
author, name, version = parse_plugin_name(
|
629
|
-
plugin_str, version_separator="=="
|
630
|
-
)
|
631
|
-
|
632
|
-
plugin = client.get_plugin(
|
633
|
-
name=name,
|
634
|
-
version=version,
|
635
|
-
author=author,
|
636
|
-
)
|
637
|
-
|
638
|
-
if plugin and plugin.index_url and plugin.package_name:
|
639
|
-
internal_requirements[plugin.index_url].append(
|
640
|
-
plugin.package_name
|
641
|
-
)
|
642
|
-
if plugin.requirements:
|
643
|
-
pypi_requirements.extend(plugin.requirements)
|
644
|
-
else:
|
645
|
-
display_name = plugin_display_name(name, version, author)
|
646
|
-
logger.warning(
|
647
|
-
"Hub plugin `%s` does not exist or cannot be installed."
|
648
|
-
"Skipping installation of this plugin.",
|
649
|
-
display_name,
|
650
|
-
)
|
651
|
-
|
652
|
-
pypi_requirements = sorted(set(pypi_requirements))
|
653
|
-
return dict(internal_requirements), pypi_requirements
|
654
|
-
|
655
562
|
@staticmethod
|
656
563
|
def _generate_zenml_pipeline_dockerfile(
|
657
564
|
parent_image: str,
|
zenml/utils/source_utils.py
CHANGED
@@ -35,14 +35,19 @@ from typing import (
|
|
35
35
|
from zenml.config.source import (
|
36
36
|
CodeRepositorySource,
|
37
37
|
DistributionPackageSource,
|
38
|
+
NotebookSource,
|
38
39
|
Source,
|
39
40
|
SourceType,
|
40
41
|
)
|
41
42
|
from zenml.constants import ENV_ZENML_CUSTOM_SOURCE_ROOT
|
42
43
|
from zenml.environment import Environment
|
43
44
|
from zenml.logger import get_logger
|
45
|
+
from zenml.utils import notebook_utils
|
44
46
|
|
45
47
|
logger = get_logger(__name__)
|
48
|
+
|
49
|
+
ZENML_SOURCE_ATTRIBUTE_NAME = "__zenml_source__"
|
50
|
+
|
46
51
|
NoneType = type(None)
|
47
52
|
NoneTypeSource = Source(
|
48
53
|
module=NoneType.__module__, attribute="NoneType", type=SourceType.BUILTIN
|
@@ -58,10 +63,13 @@ BuiltinFunctionTypeSource = Source(
|
|
58
63
|
type=SourceType.BUILTIN,
|
59
64
|
)
|
60
65
|
|
66
|
+
|
61
67
|
_CUSTOM_SOURCE_ROOT: Optional[str] = os.getenv(
|
62
68
|
ENV_ZENML_CUSTOM_SOURCE_ROOT, None
|
63
69
|
)
|
64
70
|
|
71
|
+
_SHARED_TEMPDIR: Optional[str] = None
|
72
|
+
|
65
73
|
|
66
74
|
def load(source: Union[Source, str]) -> Any:
|
67
75
|
"""Load a source or import path.
|
@@ -105,6 +113,14 @@ def load(source: Union[Source, str]) -> Any:
|
|
105
113
|
source.version,
|
106
114
|
source.import_path,
|
107
115
|
)
|
116
|
+
elif source.type == SourceType.NOTEBOOK:
|
117
|
+
if Environment.in_notebook():
|
118
|
+
# If we're in a notebook, we don't need to do anything as the
|
119
|
+
# loading from the __main__ module should work just fine.
|
120
|
+
pass
|
121
|
+
else:
|
122
|
+
notebook_source = NotebookSource.model_validate(dict(source))
|
123
|
+
return _try_to_load_notebook_source(notebook_source)
|
108
124
|
elif source.type in {SourceType.USER, SourceType.UNKNOWN}:
|
109
125
|
# Unknown source might also refer to a user file, include source
|
110
126
|
# root in python path just to be sure
|
@@ -152,6 +168,9 @@ def resolve(
|
|
152
168
|
return FunctionTypeSource
|
153
169
|
elif obj is BuiltinFunctionType:
|
154
170
|
return BuiltinFunctionTypeSource
|
171
|
+
elif source := getattr(obj, ZENML_SOURCE_ATTRIBUTE_NAME, None):
|
172
|
+
assert isinstance(source, Source)
|
173
|
+
return source
|
155
174
|
elif isinstance(obj, ModuleType):
|
156
175
|
module = obj
|
157
176
|
attribute_name = None
|
@@ -216,6 +235,16 @@ def resolve(
|
|
216
235
|
else:
|
217
236
|
# Fallback to an unknown source if we can't find the package
|
218
237
|
source_type = SourceType.UNKNOWN
|
238
|
+
elif source_type == SourceType.NOTEBOOK:
|
239
|
+
source = NotebookSource(
|
240
|
+
module=module_name,
|
241
|
+
attribute=attribute_name,
|
242
|
+
type=source_type,
|
243
|
+
)
|
244
|
+
# Private attributes are ignored by pydantic if passed in the __init__
|
245
|
+
# method, so we set this afterwards
|
246
|
+
source._cell_code = notebook_utils.load_notebook_cell_code(obj)
|
247
|
+
return source
|
219
248
|
|
220
249
|
return Source(
|
221
250
|
module=module_name, attribute=attribute_name, type=source_type
|
@@ -362,7 +391,7 @@ def get_source_type(module: ModuleType) -> SourceType:
|
|
362
391
|
file_path = inspect.getfile(module)
|
363
392
|
except (TypeError, OSError):
|
364
393
|
if module.__name__ == "__main__" and Environment.in_notebook():
|
365
|
-
return SourceType.
|
394
|
+
return SourceType.NOTEBOOK
|
366
395
|
|
367
396
|
return SourceType.BUILTIN
|
368
397
|
|
@@ -529,6 +558,85 @@ def _load_module(
|
|
529
558
|
return importlib.import_module(module_name)
|
530
559
|
|
531
560
|
|
561
|
+
def _get_shared_temp_dir() -> str:
|
562
|
+
"""Get path to a shared temporary directory.
|
563
|
+
|
564
|
+
Returns:
|
565
|
+
Path to a shared temporary directory.
|
566
|
+
"""
|
567
|
+
global _SHARED_TEMPDIR
|
568
|
+
|
569
|
+
if not _SHARED_TEMPDIR:
|
570
|
+
import tempfile
|
571
|
+
|
572
|
+
_SHARED_TEMPDIR = tempfile.mkdtemp()
|
573
|
+
|
574
|
+
return _SHARED_TEMPDIR
|
575
|
+
|
576
|
+
|
577
|
+
def _try_to_load_notebook_source(source: NotebookSource) -> Any:
|
578
|
+
"""Helper function to load a notebook source outside of a notebook.
|
579
|
+
|
580
|
+
Args:
|
581
|
+
source: The source to load.
|
582
|
+
|
583
|
+
Raises:
|
584
|
+
RuntimeError: If the source can't be loaded.
|
585
|
+
|
586
|
+
Returns:
|
587
|
+
The loaded object.
|
588
|
+
"""
|
589
|
+
if not source.code_path or not source.replacement_module:
|
590
|
+
raise RuntimeError(
|
591
|
+
f"Failed to load {source.import_path}. This object was defined in "
|
592
|
+
"a notebook and you're trying to load it outside of a notebook. "
|
593
|
+
"This is currently only enabled for ZenML steps."
|
594
|
+
)
|
595
|
+
|
596
|
+
extract_dir = _get_shared_temp_dir()
|
597
|
+
file_path = os.path.join(extract_dir, f"{source.replacement_module}.py")
|
598
|
+
|
599
|
+
if not os.path.exists(file_path):
|
600
|
+
from zenml.utils import code_utils
|
601
|
+
|
602
|
+
logger.info(
|
603
|
+
"Downloading notebook cell content from `%s` to load `%s`.",
|
604
|
+
source.code_path,
|
605
|
+
source.import_path,
|
606
|
+
)
|
607
|
+
|
608
|
+
code_utils.download_and_extract_code(
|
609
|
+
code_path=source.code_path, extract_dir=extract_dir
|
610
|
+
)
|
611
|
+
|
612
|
+
try:
|
613
|
+
module = _load_module(
|
614
|
+
module_name=source.replacement_module, import_root=extract_dir
|
615
|
+
)
|
616
|
+
except ImportError:
|
617
|
+
raise RuntimeError(
|
618
|
+
f"Unable to load {source.import_path}. This object was defined in "
|
619
|
+
"a notebook and you're trying to load it outside of a notebook. "
|
620
|
+
"To enable this, ZenML extracts the code of your cell into a "
|
621
|
+
"python file. This means your cell code needs to be "
|
622
|
+
"self-contained:\n"
|
623
|
+
" * All required imports must be done in this cell, even if the "
|
624
|
+
"same imports already happen in previous notebook cells.\n"
|
625
|
+
" * The cell can't use any code defined in other notebook cells."
|
626
|
+
)
|
627
|
+
|
628
|
+
if source.attribute:
|
629
|
+
obj = getattr(module, source.attribute)
|
630
|
+
else:
|
631
|
+
obj = module
|
632
|
+
|
633
|
+
# Store the original notebook source so resolving this object works as
|
634
|
+
# expected
|
635
|
+
setattr(obj, ZENML_SOURCE_ATTRIBUTE_NAME, source)
|
636
|
+
|
637
|
+
return obj
|
638
|
+
|
639
|
+
|
532
640
|
def _get_package_for_module(module_name: str) -> Optional[str]:
|
533
641
|
"""Get the package name for a module.
|
534
642
|
|
@@ -1 +1 @@
|
|
1
|
-
import{j as e}from"./@radix-
|
1
|
+
import{j as e}from"./@radix-BXWm7HOa.js";import{h as s,r as t}from"./index-DhIZtpxB.js";import{E as r}from"./EmptyState-BHblM39I.js";import{H as a}from"./help-FuHlZwn0.js";import{L as o}from"./@react-router-l3lMcXA2.js";import"./@tanstack-FmcYZMuX.js";import"./@reactflow-CeVxyqYT.js";function d(){return e.jsx("div",{className:"flex min-h-screen w-full flex-col",children:e.jsx(r,{icon:e.jsx(a,{className:"h-[120px] w-[120px] fill-neutral-300"}),children:e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"mb-2 text-display-xs font-semibold",children:"We can't find the page you are looking for"}),e.jsx("p",{className:"text-lg text-theme-text-secondary",children:"You can try typing a different URL or we can bring you back to your Homepage."}),e.jsx("div",{className:"mt-5 flex justify-center",children:e.jsx(s,{size:"md",asChild:!0,children:e.jsx(o,{className:"w-min self-center whitespace-nowrap",to:t.home,children:e.jsx("span",{className:"px-0.5",children:"Go to Home"})})})})]})})})}export{d as default};
|