zenml-nightly 0.61.0.dev20240714__py3-none-any.whl → 0.62.0.dev20240719__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 +1 -1
- RELEASE_NOTES.md +40 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +2 -0
- zenml/cli/stack.py +87 -228
- zenml/cli/stack_components.py +5 -3
- zenml/constants.py +2 -0
- zenml/entrypoints/entrypoint.py +3 -1
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/constants.py +1 -0
- zenml/integrations/databricks/__init__.py +52 -0
- zenml/integrations/databricks/flavors/__init__.py +30 -0
- zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +147 -0
- zenml/integrations/databricks/model_deployers/__init__.py +20 -0
- zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
- zenml/integrations/databricks/orchestrators/__init__.py +20 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +498 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
- zenml/integrations/databricks/services/__init__.py +19 -0
- zenml/integrations/databricks/services/databricks_deployment.py +407 -0
- zenml/integrations/databricks/utils/__init__.py +14 -0
- zenml/integrations/databricks/utils/databricks_utils.py +87 -0
- zenml/integrations/great_expectations/data_validators/ge_data_validator.py +12 -8
- zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +88 -3
- zenml/integrations/huggingface/steps/accelerate_runner.py +1 -7
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +7 -0
- zenml/integrations/kubernetes/pod_settings.py +2 -0
- zenml/integrations/lightgbm/__init__.py +1 -0
- zenml/integrations/mlflow/__init__.py +1 -1
- zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +6 -2
- zenml/integrations/mlflow/services/mlflow_deployment.py +1 -1
- zenml/integrations/skypilot_lambda/__init__.py +1 -1
- zenml/materializers/built_in_materializer.py +1 -1
- zenml/materializers/cloudpickle_materializer.py +1 -1
- zenml/model/model.py +1 -1
- zenml/models/v2/core/component.py +29 -0
- zenml/models/v2/misc/full_stack.py +32 -0
- zenml/orchestrators/__init__.py +4 -0
- zenml/orchestrators/wheeled_orchestrator.py +147 -0
- zenml/service_connectors/service_connector_utils.py +349 -0
- zenml/stack_deployments/gcp_stack_deployment.py +2 -4
- zenml/steps/base_step.py +7 -5
- zenml/utils/function_utils.py +1 -1
- zenml/utils/pipeline_docker_image_builder.py +8 -0
- zenml/zen_server/dashboard/assets/{404-DpJaNHKF.js → 404-B_YdvmwS.js} +1 -1
- zenml/zen_server/dashboard/assets/{@reactflow-DJfzkHO1.js → @reactflow-l_1hUr1S.js} +1 -1
- zenml/zen_server/dashboard/assets/{AwarenessChannel-BYDLT2xC.js → AwarenessChannel-CFg5iX4Z.js} +1 -1
- zenml/zen_server/dashboard/assets/{CodeSnippet-BkOuRmyq.js → CodeSnippet-Dvkx_82E.js} +1 -1
- zenml/zen_server/dashboard/assets/CollapsibleCard-opiuBHHc.js +1 -0
- zenml/zen_server/dashboard/assets/{Commands-ZvWR1BRs.js → Commands-DoN1xrEq.js} +1 -1
- zenml/zen_server/dashboard/assets/{CopyButton-DVwLkafa.js → CopyButton-Cr7xYEPb.js} +1 -1
- zenml/zen_server/dashboard/assets/{CsvVizualization-C2IiqX4I.js → CsvVizualization-Ck-nZ43m.js} +3 -3
- zenml/zen_server/dashboard/assets/{Error-CqX0VqW_.js → Error-kLtljEOM.js} +1 -1
- zenml/zen_server/dashboard/assets/{ExecutionStatus-BoLUXR9t.js → ExecutionStatus-DguLLgTK.js} +1 -1
- zenml/zen_server/dashboard/assets/{Helpbox-LFydyVwh.js → Helpbox-BXUMP21n.js} +1 -1
- zenml/zen_server/dashboard/assets/{Infobox-DnENC0sh.js → Infobox-DSt0O-dm.js} +1 -1
- zenml/zen_server/dashboard/assets/{InlineAvatar-CbJtYr0t.js → InlineAvatar-xsrsIGE-.js} +1 -1
- zenml/zen_server/dashboard/assets/Pagination-C6X-mifw.js +1 -0
- zenml/zen_server/dashboard/assets/{SetPassword-BYBdbQDo.js → SetPassword-BXGTWiwj.js} +1 -1
- zenml/zen_server/dashboard/assets/{SuccessStep-Nx743hll.js → SuccessStep-DZC60t0x.js} +1 -1
- zenml/zen_server/dashboard/assets/{UpdatePasswordSchemas-DF9gSzE0.js → UpdatePasswordSchemas-DGvwFWO1.js} +1 -1
- zenml/zen_server/dashboard/assets/{chevron-right-double-BiEMg7rd.js → chevron-right-double-CZBOf6JM.js} +1 -1
- zenml/zen_server/dashboard/assets/cloud-only-C_yFCAkP.js +1 -0
- zenml/zen_server/dashboard/assets/index-BczVOqUf.js +55 -0
- zenml/zen_server/dashboard/assets/index-EpMIKgrI.css +1 -0
- zenml/zen_server/dashboard/assets/{login-mutation-BUnVASxp.js → login-mutation-CrHrndTI.js} +1 -1
- zenml/zen_server/dashboard/assets/logs-D8k8BVFf.js +1 -0
- zenml/zen_server/dashboard/assets/{not-found-B4VnX8gK.js → not-found-DYa4pC-C.js} +1 -1
- zenml/zen_server/dashboard/assets/{package-CsUhPmou.js → package-B3fWP-Dh.js} +1 -1
- zenml/zen_server/dashboard/assets/page-1h_sD1jz.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Sxn82W-5.js → page-1iL8aMqs.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DMOYZppS.js → page-2grKx_MY.js} +1 -1
- zenml/zen_server/dashboard/assets/page-5NCOHOsy.js +1 -0
- zenml/zen_server/dashboard/assets/{page-JyfeDUfu.js → page-8a4UMKXZ.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Bx6o0ARS.js → page-B6h3iaHJ.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BDns21Iz.js +1 -0
- zenml/zen_server/dashboard/assets/{page-3efNCDeb.js → page-BhgCDInH.js} +2 -2
- zenml/zen_server/dashboard/assets/{page-DKlIdAe5.js → page-Bi-wtWiO.js} +2 -2
- zenml/zen_server/dashboard/assets/{page-7zTHbhhI.js → page-BkeAAYwp.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-CRTJ0UuR.js → page-BkuQDIf-.js} +1 -1
- zenml/zen_server/dashboard/assets/page-BnaevhnB.js +1 -0
- zenml/zen_server/dashboard/assets/{page-BEs6jK71.js → page-Bq0YxkLV.js} +1 -1
- zenml/zen_server/dashboard/assets/page-Bs2F4eoD.js +2 -0
- zenml/zen_server/dashboard/assets/{page-CUZIGO-3.js → page-C6-UGEbH.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-Xu8JEjSU.js → page-CCNRIt_f.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-DvCvroOM.js → page-CHNxpz3n.js} +1 -1
- zenml/zen_server/dashboard/assets/{page-BpSqIf4B.js → page-DgorQFqi.js} +1 -1
- zenml/zen_server/dashboard/assets/page-K8ebxVIs.js +1 -0
- zenml/zen_server/dashboard/assets/{page-Cx67M0QT.js → page-MFQyIJd3.js} +1 -1
- zenml/zen_server/dashboard/assets/page-TgCF0P_U.js +1 -0
- zenml/zen_server/dashboard/assets/page-ZnCEe-eK.js +9 -0
- zenml/zen_server/dashboard/assets/{page-Dc_7KMQE.js → page-uA5prJGY.js} +1 -1
- zenml/zen_server/dashboard/assets/persist-D7HJNBWx.js +1 -0
- zenml/zen_server/dashboard/assets/plus-C8WOyCzt.js +1 -0
- zenml/zen_server/dashboard/assets/stack-detail-query-Cficsl6d.js +1 -0
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-7d8xi1tS.js +1 -0
- zenml/zen_server/dashboard/assets/{url-DuQMeqYA.js → url-D7mAQGUM.js} +1 -1
- zenml/zen_server/dashboard/index.html +4 -4
- 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.c8c57fb0d2132b1d3c2119e776b7dfb3.js → precache-manifest.12246c7548e71e2c4438e496360de80c.js} +4 -4
- zenml/zen_server/dashboard_legacy/service-worker.js +1 -1
- zenml/zen_server/dashboard_legacy/static/js/main.3b27024b.chunk.js +2 -0
- zenml/zen_server/dashboard_legacy/static/js/{main.382439a7.chunk.js.map → main.3b27024b.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/service_connectors_endpoints.py +57 -0
- zenml/zen_stores/migrations/versions/0.62.0_release.py +23 -0
- zenml/zen_stores/rest_zen_store.py +4 -0
- zenml/zen_stores/schemas/component_schemas.py +14 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/METADATA +2 -2
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/RECORD +116 -98
- zenml/zen_server/dashboard/assets/Pagination-DEbVUupy.js +0 -1
- zenml/zen_server/dashboard/assets/chevron-down-D_ZlKMqH.js +0 -1
- zenml/zen_server/dashboard/assets/cloud-only-DVbIeckv.js +0 -1
- zenml/zen_server/dashboard/assets/index-C_CrU4vI.js +0 -1
- zenml/zen_server/dashboard/assets/index-DK1ynKjA.js +0 -55
- zenml/zen_server/dashboard/assets/index-inApY3KQ.css +0 -1
- zenml/zen_server/dashboard/assets/page-C43QGHTt.js +0 -9
- zenml/zen_server/dashboard/assets/page-CR0OG7ss.js +0 -1
- zenml/zen_server/dashboard/assets/page-CaopxiU1.js +0 -1
- zenml/zen_server/dashboard/assets/page-D7Z399xy.js +0 -1
- zenml/zen_server/dashboard/assets/page-D93kd7Xj.js +0 -1
- zenml/zen_server/dashboard/assets/page-DMsSn3dv.js +0 -2
- zenml/zen_server/dashboard/assets/page-Hus2pr9T.js +0 -1
- zenml/zen_server/dashboard/assets/page-TKXERe16.js +0 -1
- zenml/zen_server/dashboard/assets/plus-DOeLmm7C.js +0 -1
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-CR8e3Sir.js +0 -1
- zenml/zen_server/dashboard_legacy/static/js/main.382439a7.chunk.js +0 -2
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.61.0.dev20240714.dist-info → zenml_nightly-0.62.0.dev20240719.dist-info}/entry_points.txt +0 -0
README.md
CHANGED
@@ -327,7 +327,7 @@ the Apache License Version 2.0.
|
|
327
327
|
<a href="https://github.com/zenml-io/zenml-projects">Projects Showcase</a>
|
328
328
|
<br />
|
329
329
|
<br />
|
330
|
-
🎉 Version 0.
|
330
|
+
🎉 Version 0.62.0 is out. Check out the release notes
|
331
331
|
<a href="https://github.com/zenml-io/zenml/releases">here</a>.
|
332
332
|
<br />
|
333
333
|
🖥️ Download our VS Code Extension <a href="https://marketplace.visualstudio.com/items?itemName=ZenML.zenml-vscode">here</a>.
|
RELEASE_NOTES.md
CHANGED
@@ -1,4 +1,44 @@
|
|
1
1
|
<!-- markdown-link-check-disable -->
|
2
|
+
# 0.62.0
|
3
|
+
|
4
|
+
Building on top of the last release, this release adds a new and easy way to deploy a GCP ZenML stack from the dashboard and the CLI. Give it a try by going to the `Stacks` section in the dashboard or running the `zenml stack deploy` command! For more information on this new feature, please do check out [the video and blog](https://www.zenml.io/blog/easy-mlops-pipelines) from our previous release.
|
5
|
+
|
6
|
+
We also [updated our Hugging Face integration](https://github.com/zenml-io/zenml/pull/2851) to support the automatic display of an embedded `datasets` preview pane in the ZenML Dashboard whenever you return a `Dataset` from a step. This was recently released by the Hugging Face datasets team and it allows you to easily visualize and inspect your data from the comfort of the dashboard.
|
7
|
+
|
8
|
+
## What's Changed
|
9
|
+
|
10
|
+
* Fix release action docker limit by @schustmi in https://github.com/zenml-io/zenml/pull/2837
|
11
|
+
* Upgrade ruff and yamlfix to latest versions before running formatting by @christianversloot in https://github.com/zenml-io/zenml/pull/2577
|
12
|
+
* Fixed edge-case where step run is stored incompletely by @AlexejPenner in https://github.com/zenml-io/zenml/pull/2827
|
13
|
+
* Docs for stack registration + deployment wizards by @htahir1 in https://github.com/zenml-io/zenml/pull/2814
|
14
|
+
* Make upgrade checks in formatting script optional by @avishniakov in https://github.com/zenml-io/zenml/pull/2839
|
15
|
+
* Enable migration testing for version 0.61.0 by @schustmi in https://github.com/zenml-io/zenml/pull/2836
|
16
|
+
* One-click GCP stack deployments by @stefannica in https://github.com/zenml-io/zenml/pull/2833
|
17
|
+
* Only login to docker for PRs with secret access by @schustmi in https://github.com/zenml-io/zenml/pull/2842
|
18
|
+
* Add GCP Stack creation Wizard (CLI) by @avishniakov in https://github.com/zenml-io/zenml/pull/2826
|
19
|
+
* Update onboarding by @schustmi in https://github.com/zenml-io/zenml/pull/2794
|
20
|
+
* Merged log files in Step Ops steps might be not available on main process, due to merge in the step op by @avishniakov in https://github.com/zenml-io/zenml/pull/2795
|
21
|
+
* Fix some broken links, copy paste commands, and made secrets more visible by @htahir1 in https://github.com/zenml-io/zenml/pull/2848
|
22
|
+
* Update stack deployment docs and other small fixes by @stefannica in https://github.com/zenml-io/zenml/pull/2846
|
23
|
+
* Improved the `StepInterfaceError` message for missing inputs by @AlexejPenner in https://github.com/zenml-io/zenml/pull/2849
|
24
|
+
* add image pull secrets to k8s pod settings by @wjayesh in https://github.com/zenml-io/zenml/pull/2847
|
25
|
+
* Include apt installation of libgomp1 for docker images with lightgbm by @AlexejPenner in https://github.com/zenml-io/zenml/pull/2813
|
26
|
+
* Patch filter mflow by stage by @whoknowsB in https://github.com/zenml-io/zenml/pull/2798
|
27
|
+
* Bump mlflow to version 2.14.2 by @christianversloot in https://github.com/zenml-io/zenml/pull/2825
|
28
|
+
* Fix Accelerate string arguments passing by @avishniakov in https://github.com/zenml-io/zenml/pull/2845
|
29
|
+
* Fix CI by @schustmi in https://github.com/zenml-io/zenml/pull/2850
|
30
|
+
* Added some visualizations for the HF dataset by @htahir1 in https://github.com/zenml-io/zenml/pull/2851
|
31
|
+
* Fix skypilot versioning for the lambda integration by @wjayesh in https://github.com/zenml-io/zenml/pull/2853
|
32
|
+
* Improve custom visualization docs by @htahir1 in https://github.com/zenml-io/zenml/pull/2855
|
33
|
+
* Fix list typo by @htahir1 in https://github.com/zenml-io/zenml/pull/2856
|
34
|
+
* Endpoint to get existing and prospective resources for service connector by @avishniakov in https://github.com/zenml-io/zenml/pull/2854
|
35
|
+
* Databricks integrations by @safoinme in https://github.com/zenml-io/zenml/pull/2823
|
36
|
+
|
37
|
+
## New Contributors
|
38
|
+
* @whoknowsB made their first contribution in https://github.com/zenml-io/zenml/pull/2798
|
39
|
+
|
40
|
+
**Full Changelog**: https://github.com/zenml-io/zenml/compare/0.61.0...0.62.0
|
41
|
+
|
2
42
|
# 0.61.0
|
3
43
|
|
4
44
|
This release comes with a new and easy way to deploy an AWS ZenML stack from the dashboard and the CLI. Give it a try by going to the `Stacks` section in the dashboard or running the `zenml stack deploy` command!
|
zenml/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.62.0.dev20240719
|
zenml/__init__.py
CHANGED
@@ -56,6 +56,7 @@ from zenml.new.pipelines.pipeline_decorator import pipeline
|
|
56
56
|
from zenml.new.steps.step_decorator import step
|
57
57
|
from zenml.new.steps.step_context import get_step_context
|
58
58
|
from zenml.steps.utils import log_step_metadata
|
59
|
+
from zenml.entrypoints import entrypoint
|
59
60
|
|
60
61
|
__all__ = [
|
61
62
|
"ArtifactConfig",
|
@@ -74,4 +75,5 @@ __all__ = [
|
|
74
75
|
"save_artifact",
|
75
76
|
"show",
|
76
77
|
"step",
|
78
|
+
"entrypoint",
|
77
79
|
]
|
zenml/cli/stack.py
CHANGED
@@ -83,9 +83,10 @@ from zenml.models.v2.misc.full_stack import (
|
|
83
83
|
ComponentInfo,
|
84
84
|
FullStackRequest,
|
85
85
|
ServiceConnectorInfo,
|
86
|
+
ServiceConnectorResourcesInfo,
|
86
87
|
)
|
87
|
-
from zenml.
|
88
|
-
|
88
|
+
from zenml.service_connectors.service_connector_utils import (
|
89
|
+
get_resources_options_from_resource_model_for_full_stack,
|
89
90
|
)
|
90
91
|
from zenml.utils.dashboard_utils import get_component_url, get_stack_url
|
91
92
|
from zenml.utils.io_utils import create_dir_recursive_if_not_exists
|
@@ -329,6 +330,13 @@ def register_stack(
|
|
329
330
|
auto_configure=True,
|
330
331
|
verify=False,
|
331
332
|
)
|
333
|
+
except NotImplementedError:
|
334
|
+
cli_utils.warning(
|
335
|
+
f"The {provider.upper()} service connector libraries are not "
|
336
|
+
"installed properly. Please run `zenml integration install "
|
337
|
+
f"{provider}` and try again to enable auto-discovery of the "
|
338
|
+
"connection configuration."
|
339
|
+
)
|
332
340
|
except Exception:
|
333
341
|
pass
|
334
342
|
if service_connector_response:
|
@@ -390,8 +398,21 @@ def register_stack(
|
|
390
398
|
labels["zenml:wizard"] = "true"
|
391
399
|
if provider:
|
392
400
|
labels["zenml:provider"] = provider
|
393
|
-
|
394
|
-
|
401
|
+
resources_info = None
|
402
|
+
# explore the service connector
|
403
|
+
with console.status(
|
404
|
+
"Exploring resources available to the service connector...\n"
|
405
|
+
):
|
406
|
+
resources_info = (
|
407
|
+
get_resources_options_from_resource_model_for_full_stack(
|
408
|
+
connector_details=service_connector
|
409
|
+
)
|
410
|
+
)
|
411
|
+
if resources_info is None:
|
412
|
+
cli_utils.error(
|
413
|
+
f"Failed to fetch service connector resources information for {service_connector}..."
|
414
|
+
)
|
415
|
+
|
395
416
|
# create components
|
396
417
|
needed_components = (
|
397
418
|
(StackComponentType.ARTIFACT_STORE, artifact_store),
|
@@ -408,21 +429,37 @@ def register_stack(
|
|
408
429
|
else:
|
409
430
|
if isinstance(service_connector, UUID):
|
410
431
|
# find existing components under same connector
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
432
|
+
if (
|
433
|
+
component_type
|
434
|
+
in resources_info.components_resources_info
|
435
|
+
):
|
436
|
+
existing_components = [
|
437
|
+
existing_response
|
438
|
+
for res_info in resources_info.components_resources_info[
|
439
|
+
component_type
|
440
|
+
]
|
441
|
+
for existing_response in res_info.connected_through_service_connector
|
442
|
+
]
|
443
|
+
|
444
|
+
# if some existing components are found - prompt user what to do
|
445
|
+
component_selected: Optional[int] = None
|
419
446
|
component_selected = cli_utils.multi_choice_prompt(
|
420
447
|
object_type=component_type.value.replace("_", " "),
|
421
448
|
choices=[
|
422
|
-
[
|
423
|
-
|
449
|
+
[
|
450
|
+
component.flavor,
|
451
|
+
component.name,
|
452
|
+
component.configuration or "",
|
453
|
+
component.connector_resource_id,
|
454
|
+
]
|
455
|
+
for component in existing_components
|
456
|
+
],
|
457
|
+
headers=[
|
458
|
+
"Type",
|
459
|
+
"Name",
|
460
|
+
"Configuration",
|
461
|
+
"Connected as",
|
424
462
|
],
|
425
|
-
headers=["Name"],
|
426
463
|
prompt_text=f"We found these {component_type.value.replace('_', ' ')} "
|
427
464
|
"connected using the current service connector. Do you "
|
428
465
|
"want to create a new one or use existing one?",
|
@@ -433,61 +470,17 @@ def register_stack(
|
|
433
470
|
component_selected = None
|
434
471
|
|
435
472
|
if component_selected is None:
|
436
|
-
if service_connector_resource_model is None:
|
437
|
-
with console.status(
|
438
|
-
"Exploring resources available to the service connector...\n"
|
439
|
-
):
|
440
|
-
if isinstance(service_connector, UUID):
|
441
|
-
service_connector_resource_model = (
|
442
|
-
client.verify_service_connector(
|
443
|
-
service_connector
|
444
|
-
)
|
445
|
-
)
|
446
|
-
existing_service_connector_info = (
|
447
|
-
client.get_service_connector(
|
448
|
-
service_connector
|
449
|
-
)
|
450
|
-
)
|
451
|
-
can_generate_long_tokens = not existing_service_connector_info.configuration.get(
|
452
|
-
"generate_temporary_tokens", True
|
453
|
-
)
|
454
|
-
else:
|
455
|
-
_, service_connector_resource_model = (
|
456
|
-
client.create_service_connector(
|
457
|
-
name=stack_name,
|
458
|
-
connector_type=service_connector.type,
|
459
|
-
auth_method=service_connector.auth_method,
|
460
|
-
configuration=service_connector.configuration,
|
461
|
-
register=False,
|
462
|
-
)
|
463
|
-
)
|
464
|
-
can_generate_long_tokens = True
|
465
|
-
if service_connector_resource_model is None:
|
466
|
-
cli_utils.error(
|
467
|
-
f"Failed to validate service connector {service_connector}..."
|
468
|
-
)
|
469
|
-
if provider is None:
|
470
|
-
if isinstance(
|
471
|
-
service_connector_resource_model.connector_type,
|
472
|
-
str,
|
473
|
-
):
|
474
|
-
provider = (
|
475
|
-
service_connector_resource_model.connector_type
|
476
|
-
)
|
477
|
-
else:
|
478
|
-
provider = service_connector_resource_model.connector_type.connector_type
|
479
|
-
|
480
473
|
component_info = _get_stack_component_info(
|
481
474
|
component_type=component_type.value,
|
482
|
-
cloud_provider=provider
|
483
|
-
|
475
|
+
cloud_provider=provider
|
476
|
+
or resources_info.connector_type,
|
477
|
+
resources_info=resources_info,
|
484
478
|
service_connector_index=0,
|
485
|
-
can_generate_long_tokens=can_generate_long_tokens,
|
486
479
|
)
|
487
480
|
component_name = stack_name
|
488
481
|
created_objects.add(component_type.value)
|
489
482
|
else:
|
490
|
-
selected_component = existing_components
|
483
|
+
selected_component = existing_components[
|
491
484
|
component_selected
|
492
485
|
]
|
493
486
|
component_info = selected_component.id
|
@@ -1752,12 +1745,12 @@ def deploy(
|
|
1752
1745
|
Markdown(
|
1753
1746
|
"## Configuration\n"
|
1754
1747
|
"You will be asked to provide the following configuration "
|
1755
|
-
"values during the deployment process
|
1756
|
-
)
|
1748
|
+
"values during the deployment process:"
|
1749
|
+
),
|
1750
|
+
"\n",
|
1757
1751
|
)
|
1758
1752
|
|
1759
1753
|
console.print(
|
1760
|
-
"\n",
|
1761
1754
|
deployment_config.configuration,
|
1762
1755
|
no_wrap=True,
|
1763
1756
|
overflow="ignore",
|
@@ -2349,7 +2342,7 @@ def _get_service_connector_info(
|
|
2349
2342
|
choices.append([value.name, required])
|
2350
2343
|
|
2351
2344
|
selected_auth_idx = cli_utils.multi_choice_prompt(
|
2352
|
-
object_type=f"authentication methods for {cloud_provider}",
|
2345
|
+
object_type=f"authentication methods for {cloud_provider.upper()}",
|
2353
2346
|
choices=choices,
|
2354
2347
|
headers=headers,
|
2355
2348
|
prompt_text="Please choose one of the authentication option above",
|
@@ -2393,10 +2386,7 @@ def _get_service_connector_info(
|
|
2393
2386
|
def _get_stack_component_info(
|
2394
2387
|
component_type: str,
|
2395
2388
|
cloud_provider: str,
|
2396
|
-
|
2397
|
-
ServiceConnectorTypedResourcesModel
|
2398
|
-
],
|
2399
|
-
can_generate_long_tokens: bool,
|
2389
|
+
resources_info: ServiceConnectorResourcesInfo,
|
2400
2390
|
service_connector_index: Optional[int] = None,
|
2401
2391
|
) -> ComponentInfo:
|
2402
2392
|
"""Get a stack component info with given type and service connector.
|
@@ -2404,8 +2394,7 @@ def _get_stack_component_info(
|
|
2404
2394
|
Args:
|
2405
2395
|
component_type: The type of component to create.
|
2406
2396
|
cloud_provider: The cloud provider to use.
|
2407
|
-
|
2408
|
-
can_generate_long_tokens: Whether connector can generate long-living tokens.
|
2397
|
+
resources_info: The resources info of the service connector.
|
2409
2398
|
service_connector_index: The index of the service connector to use.
|
2410
2399
|
|
2411
2400
|
Returns:
|
@@ -2420,62 +2409,30 @@ def _get_stack_component_info(
|
|
2420
2409
|
if cloud_provider not in {"aws", "azure", "gcp"}:
|
2421
2410
|
raise ValueError(f"Unknown cloud provider {cloud_provider}")
|
2422
2411
|
|
2423
|
-
AWS_DOCS = (
|
2424
|
-
"https://docs.zenml.io/how-to/auth-management/aws-service-connector"
|
2425
|
-
)
|
2426
|
-
GCP_DOCS = (
|
2427
|
-
"https://docs.zenml.io/how-to/auth-management/gcp-service-connector"
|
2428
|
-
)
|
2429
|
-
|
2430
2412
|
flavor = "undefined"
|
2431
2413
|
service_connector_resource_id = None
|
2432
2414
|
config = {}
|
2415
|
+
choices = [
|
2416
|
+
[cri.flavor, resource_id]
|
2417
|
+
for cri in resources_info.components_resources_info[
|
2418
|
+
StackComponentType(component_type)
|
2419
|
+
]
|
2420
|
+
for resource_id in cri.accessible_by_service_connector
|
2421
|
+
]
|
2433
2422
|
if component_type == "artifact_store":
|
2434
|
-
available_storages: List[str] = []
|
2435
|
-
if cloud_provider == "aws":
|
2436
|
-
for each in service_connector_resource_models:
|
2437
|
-
if each.resource_type == "s3-bucket":
|
2438
|
-
available_storages = each.resource_ids or []
|
2439
|
-
flavor = "s3"
|
2440
|
-
if not available_storages:
|
2441
|
-
cli_utils.error(
|
2442
|
-
"We were unable to find any S3 buckets available "
|
2443
|
-
"to configured service connector. Please, verify "
|
2444
|
-
"that needed permission are granted for the "
|
2445
|
-
"service connector.\nDocumentation for the S3 "
|
2446
|
-
"Buckets configuration can be found at "
|
2447
|
-
f"{AWS_DOCS}#s3-bucket"
|
2448
|
-
)
|
2449
|
-
elif cloud_provider == "azure":
|
2450
|
-
flavor = "azure"
|
2451
|
-
elif cloud_provider == "gcp":
|
2452
|
-
flavor = "gcp"
|
2453
|
-
for each in service_connector_resource_models:
|
2454
|
-
if each.resource_type == "gcs-bucket":
|
2455
|
-
available_storages = each.resource_ids or []
|
2456
|
-
if not available_storages:
|
2457
|
-
cli_utils.error(
|
2458
|
-
"We were unable to find any GCS buckets available "
|
2459
|
-
"to configured service connector. Please, verify "
|
2460
|
-
"that needed permission are granted for the "
|
2461
|
-
"service connector.\nDocumentation for the GCS "
|
2462
|
-
"Buckets configuration can be found at "
|
2463
|
-
f"{GCP_DOCS}#gcs-bucket"
|
2464
|
-
)
|
2465
|
-
|
2466
2423
|
selected_storage_idx = cli_utils.multi_choice_prompt(
|
2467
2424
|
object_type=f"{cloud_provider.upper()} storages",
|
2468
|
-
choices=
|
2469
|
-
headers=["Storage"],
|
2425
|
+
choices=choices,
|
2426
|
+
headers=["Artifact Store Type", "Storage"],
|
2470
2427
|
prompt_text="Please choose one of the storages for the new artifact store:",
|
2471
2428
|
)
|
2472
2429
|
if selected_storage_idx is None:
|
2473
2430
|
cli_utils.error("No storage selected.")
|
2474
2431
|
|
2475
|
-
selected_storage =
|
2432
|
+
selected_storage = choices[selected_storage_idx]
|
2476
2433
|
|
2477
|
-
config = {"path": selected_storage}
|
2478
|
-
service_connector_resource_id = selected_storage
|
2434
|
+
config = {"path": selected_storage[1]}
|
2435
|
+
service_connector_resource_id = selected_storage[1]
|
2479
2436
|
elif component_type == "orchestrator":
|
2480
2437
|
|
2481
2438
|
def query_gcp_region(compute_type: str) -> str:
|
@@ -2492,139 +2449,41 @@ def _get_stack_component_info(
|
|
2492
2449
|
)
|
2493
2450
|
return region
|
2494
2451
|
|
2495
|
-
if cloud_provider == "aws":
|
2496
|
-
available_orchestrators = []
|
2497
|
-
for each in service_connector_resource_models:
|
2498
|
-
types = []
|
2499
|
-
if each.resource_type == "aws-generic":
|
2500
|
-
types = ["Sagemaker"]
|
2501
|
-
if can_generate_long_tokens:
|
2502
|
-
types.append("Skypilot (EC2)")
|
2503
|
-
if each.resource_type == "kubernetes-cluster":
|
2504
|
-
types = ["Kubernetes"]
|
2505
|
-
|
2506
|
-
if each.resource_ids:
|
2507
|
-
for orchestrator in each.resource_ids:
|
2508
|
-
for t in types:
|
2509
|
-
available_orchestrators.append([t, orchestrator])
|
2510
|
-
if not available_orchestrators:
|
2511
|
-
cli_utils.error(
|
2512
|
-
"We were unable to find any orchestrator engines "
|
2513
|
-
"available to the service connector. Please, verify "
|
2514
|
-
"that needed permission are granted for the "
|
2515
|
-
"service connector.\nDocumentation for the Generic "
|
2516
|
-
"AWS resource configuration can be found at "
|
2517
|
-
f"{AWS_DOCS}#generic-aws-resource\n"
|
2518
|
-
"Documentation for the Kubernetes resource "
|
2519
|
-
"configuration can be found at "
|
2520
|
-
f"{AWS_DOCS}#eks-kubernetes-cluster"
|
2521
|
-
)
|
2522
|
-
elif cloud_provider == "gcp":
|
2523
|
-
available_orchestrators = []
|
2524
|
-
for each in service_connector_resource_models:
|
2525
|
-
types = []
|
2526
|
-
if each.resource_type == "gcp-generic":
|
2527
|
-
types = ["Vertex AI"]
|
2528
|
-
if can_generate_long_tokens:
|
2529
|
-
types.append("Skypilot (Compute)")
|
2530
|
-
if each.resource_type == "kubernetes-cluster":
|
2531
|
-
types = ["Kubernetes"]
|
2532
|
-
|
2533
|
-
if each.resource_ids:
|
2534
|
-
for orchestrator in each.resource_ids:
|
2535
|
-
for t in types:
|
2536
|
-
available_orchestrators.append([t, orchestrator])
|
2537
|
-
if not available_orchestrators:
|
2538
|
-
cli_utils.error(
|
2539
|
-
"We were unable to find any orchestrator engines "
|
2540
|
-
"available to the service connector. Please, verify "
|
2541
|
-
"that needed permission are granted for the "
|
2542
|
-
"service connector.\nDocumentation for the Generic "
|
2543
|
-
"GCP resource configuration can be found at "
|
2544
|
-
f"{GCP_DOCS}#generic-gcp-resource\n"
|
2545
|
-
"Documentation for the GKE Kubernetes resource "
|
2546
|
-
"configuration can be found at "
|
2547
|
-
f"{GCP_DOCS}#gke-kubernetes-cluster"
|
2548
|
-
)
|
2549
|
-
elif cloud_provider == "azure":
|
2550
|
-
pass
|
2551
|
-
|
2552
2452
|
selected_orchestrator_idx = cli_utils.multi_choice_prompt(
|
2553
2453
|
object_type=f"orchestrators on {cloud_provider.upper()}",
|
2554
|
-
choices=
|
2555
|
-
headers=["Orchestrator Type", "
|
2454
|
+
choices=choices,
|
2455
|
+
headers=["Orchestrator Type", "Details"],
|
2556
2456
|
prompt_text="Please choose one of the orchestrators for the new orchestrator:",
|
2557
2457
|
)
|
2558
2458
|
if selected_orchestrator_idx is None:
|
2559
2459
|
cli_utils.error("No orchestrator selected.")
|
2560
2460
|
|
2561
|
-
selected_orchestrator =
|
2562
|
-
selected_orchestrator_idx
|
2563
|
-
]
|
2461
|
+
selected_orchestrator = choices[selected_orchestrator_idx]
|
2564
2462
|
|
2565
2463
|
config = {}
|
2566
|
-
|
2567
|
-
|
2464
|
+
flavor = selected_orchestrator[0]
|
2465
|
+
if flavor == "sagemaker":
|
2568
2466
|
execution_role = Prompt.ask("Enter an execution role ARN:")
|
2569
2467
|
config["execution_role"] = execution_role
|
2570
|
-
elif
|
2571
|
-
flavor = "vm_aws"
|
2468
|
+
elif flavor == "vm_aws":
|
2572
2469
|
config["region"] = selected_orchestrator[1]
|
2573
|
-
elif
|
2574
|
-
flavor = "vm_gcp"
|
2470
|
+
elif flavor == "vm_azure":
|
2575
2471
|
config["region"] = query_gcp_region("Skypilot cluster")
|
2576
|
-
elif
|
2577
|
-
flavor = "vertex"
|
2472
|
+
elif flavor == "vertex":
|
2578
2473
|
config["location"] = query_gcp_region("Vertex AI job")
|
2579
|
-
elif selected_orchestrator[0] == "Kubernetes":
|
2580
|
-
flavor = "kubernetes"
|
2581
|
-
else:
|
2582
|
-
raise ValueError(
|
2583
|
-
f"Unknown orchestrator type {selected_orchestrator[0]}"
|
2584
|
-
)
|
2585
2474
|
service_connector_resource_id = selected_orchestrator[1]
|
2586
2475
|
elif component_type == "container_registry":
|
2587
|
-
|
2588
|
-
def _get_registries(registry_name: str, docs_link: str) -> List[str]:
|
2589
|
-
available_registries: List[str] = []
|
2590
|
-
for each in service_connector_resource_models:
|
2591
|
-
if each.resource_type == "docker-registry":
|
2592
|
-
available_registries = each.resource_ids or []
|
2593
|
-
if not available_registries:
|
2594
|
-
cli_utils.error(
|
2595
|
-
"We were unable to find any container registries "
|
2596
|
-
"available to the service connector. Please, verify "
|
2597
|
-
"that needed permission are granted for the "
|
2598
|
-
f"service connector.\nDocumentation for the {registry_name} "
|
2599
|
-
"container registry resource configuration can "
|
2600
|
-
f"be found at {docs_link}"
|
2601
|
-
)
|
2602
|
-
return available_registries
|
2603
|
-
|
2604
|
-
if cloud_provider == "aws":
|
2605
|
-
flavor = "aws"
|
2606
|
-
available_registries = _get_registries(
|
2607
|
-
"ECR", f"{AWS_DOCS}#ecr-container-registry"
|
2608
|
-
)
|
2609
|
-
if cloud_provider == "gcp":
|
2610
|
-
flavor = "gcp"
|
2611
|
-
available_registries = _get_registries(
|
2612
|
-
"GCR", f"{GCP_DOCS}#gcr-container-registry"
|
2613
|
-
)
|
2614
|
-
if cloud_provider == "azure":
|
2615
|
-
flavor = "azure"
|
2616
|
-
|
2617
2476
|
selected_registry_idx = cli_utils.multi_choice_prompt(
|
2618
2477
|
object_type=f"{cloud_provider.upper()} registries",
|
2619
|
-
choices=
|
2620
|
-
headers=["Container Registry"],
|
2478
|
+
choices=choices,
|
2479
|
+
headers=["Container Registry Type", "Container Registry"],
|
2621
2480
|
prompt_text="Please choose one of the registries for the new container registry:",
|
2622
2481
|
)
|
2623
2482
|
if selected_registry_idx is None:
|
2624
2483
|
cli_utils.error("No container registry selected.")
|
2625
|
-
selected_registry =
|
2626
|
-
config = {"uri": selected_registry}
|
2627
|
-
service_connector_resource_id = selected_registry
|
2484
|
+
selected_registry = choices[selected_registry_idx]
|
2485
|
+
config = {"uri": selected_registry[1]}
|
2486
|
+
service_connector_resource_id = selected_registry[1]
|
2628
2487
|
else:
|
2629
2488
|
raise ValueError(f"Unknown component type {component_type}")
|
2630
2489
|
|
zenml/cli/stack_components.py
CHANGED
@@ -138,14 +138,16 @@ def generate_stack_component_describe_command(
|
|
138
138
|
|
139
139
|
if component_.connector:
|
140
140
|
# We also need the flavor to get the connector requirements
|
141
|
-
|
141
|
+
connector_requirements = client.get_flavor_by_name_and_type(
|
142
142
|
name=component_.flavor, component_type=component_type
|
143
|
-
)
|
143
|
+
).connector_requirements
|
144
|
+
else:
|
145
|
+
connector_requirements = None
|
144
146
|
|
145
147
|
cli_utils.print_stack_component_configuration(
|
146
148
|
component=component_,
|
147
149
|
active_status=component_.id == active_component_id,
|
148
|
-
connector_requirements=
|
150
|
+
connector_requirements=connector_requirements,
|
149
151
|
)
|
150
152
|
|
151
153
|
print_model_url(get_component_url(component_))
|
zenml/constants.py
CHANGED
@@ -173,6 +173,7 @@ ENV_ZENML_PIPELINE_API_TOKEN_EXPIRES_MINUTES = (
|
|
173
173
|
"ZENML_PIPELINE_API_TOKEN_EXPIRES_MINUTES"
|
174
174
|
)
|
175
175
|
ENV_ZENML_IGNORE_FAILURE_HOOK = "ZENML_IGNORE_FAILURE_HOOK"
|
176
|
+
ENV_ZENML_CUSTOM_SOURCE_ROOT = "ZENML_CUSTOM_SOURCE_ROOT"
|
176
177
|
|
177
178
|
# ZenML Server environment variables
|
178
179
|
ENV_ZENML_SERVER_PREFIX = "ZENML_SERVER_"
|
@@ -375,6 +376,7 @@ SERVICE_CONNECTOR_CLIENT = "/client"
|
|
375
376
|
SERVICE_CONNECTOR_RESOURCES = "/resources"
|
376
377
|
SERVICE_CONNECTOR_TYPES = "/service_connector_types"
|
377
378
|
SERVICE_CONNECTOR_VERIFY = "/verify"
|
379
|
+
SERVICE_CONNECTOR_FULL_STACK = "/full_stack_resources"
|
378
380
|
MODELS = "/models"
|
379
381
|
MODEL_VERSIONS = "/model_versions"
|
380
382
|
MODEL_VERSION_ARTIFACTS = "/model_version_artifacts"
|
zenml/entrypoints/entrypoint.py
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
import argparse
|
17
17
|
import logging
|
18
|
+
import os
|
18
19
|
import sys
|
19
20
|
|
20
21
|
from zenml import constants
|
@@ -44,7 +45,8 @@ def main() -> None:
|
|
44
45
|
parser = argparse.ArgumentParser()
|
45
46
|
parser.add_argument(f"--{ENTRYPOINT_CONFIG_SOURCE_OPTION}", required=True)
|
46
47
|
args, remaining_args = parser.parse_known_args()
|
47
|
-
|
48
|
+
if os.environ.get(constants.ENV_ZENML_CUSTOM_SOURCE_ROOT):
|
49
|
+
source_utils.set_custom_source_root(source_root=os.getcwd())
|
48
50
|
entrypoint_config_class = source_utils.load_and_validate_class(
|
49
51
|
args.entrypoint_config_source,
|
50
52
|
expected_class=BaseEntrypointConfiguration,
|
zenml/integrations/__init__.py
CHANGED
@@ -23,6 +23,7 @@ from zenml.integrations.aws import AWSIntegration # noqa
|
|
23
23
|
from zenml.integrations.azure import AzureIntegration # noqa
|
24
24
|
from zenml.integrations.bentoml import BentoMLIntegration # noqa
|
25
25
|
from zenml.integrations.bitbucket import BitbucketIntegration # noqa
|
26
|
+
from zenml.integrations.databricks import DatabricksIntegration # noqa
|
26
27
|
from zenml.integrations.comet import CometIntegration # noqa
|
27
28
|
from zenml.integrations.deepchecks import DeepchecksIntegration # noqa
|
28
29
|
from zenml.integrations.discord import DiscordIntegration # noqa
|
zenml/integrations/constants.py
CHANGED
@@ -0,0 +1,52 @@
|
|
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
|
+
"""Initialization of the Databricks integration for ZenML."""
|
15
|
+
|
16
|
+
from typing import List, Type
|
17
|
+
|
18
|
+
from zenml.integrations.constants import (
|
19
|
+
DATABRICKS,
|
20
|
+
)
|
21
|
+
from zenml.integrations.integration import Integration
|
22
|
+
from zenml.stack import Flavor
|
23
|
+
|
24
|
+
DATABRICKS_ORCHESTRATOR_FLAVOR = "databricks"
|
25
|
+
DATABRICKS_MODEL_DEPLOYER_FLAVOR = "databricks"
|
26
|
+
DATABRICKS_SERVICE_ARTIFACT = "databricks_deployment_service"
|
27
|
+
|
28
|
+
|
29
|
+
class DatabricksIntegration(Integration):
|
30
|
+
"""Definition of Databricks Integration for ZenML."""
|
31
|
+
|
32
|
+
NAME = DATABRICKS
|
33
|
+
REQUIREMENTS = ["databricks-sdk==0.28.0"]
|
34
|
+
|
35
|
+
@classmethod
|
36
|
+
def flavors(cls) -> List[Type[Flavor]]:
|
37
|
+
"""Declare the stack component flavors for the Databricks integration.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
List of stack component flavors for this integration.
|
41
|
+
"""
|
42
|
+
from zenml.integrations.databricks.flavors import (
|
43
|
+
DatabricksOrchestratorFlavor,
|
44
|
+
DatabricksModelDeployerFlavor,
|
45
|
+
)
|
46
|
+
|
47
|
+
return [
|
48
|
+
DatabricksOrchestratorFlavor,
|
49
|
+
DatabricksModelDeployerFlavor,
|
50
|
+
]
|
51
|
+
|
52
|
+
DatabricksIntegration.check_installation()
|