zenml-nightly 0.63.0.dev20240801__py3-none-any.whl → 0.64.0.dev20240809__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.dev20240809.dist-info}/METADATA +3 -3
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240809.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.dev20240809.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.63.0.dev20240801.dist-info → zenml_nightly-0.64.0.dev20240809.dist-info}/entry_points.txt +0 -0
@@ -496,6 +496,108 @@ class GCPAuthenticationMethods(StrEnum):
|
|
496
496
|
IMPERSONATION = "impersonation"
|
497
497
|
|
498
498
|
|
499
|
+
try:
|
500
|
+
from google.auth.aws import _DefaultAwsSecurityCredentialsSupplier
|
501
|
+
|
502
|
+
class ZenMLAwsSecurityCredentialsSupplier(
|
503
|
+
_DefaultAwsSecurityCredentialsSupplier # type: ignore[misc]
|
504
|
+
):
|
505
|
+
"""An improved version of the GCP external account credential supplier for AWS.
|
506
|
+
|
507
|
+
The original GCP external account credential supplier only provides
|
508
|
+
rudimentary support for extracting AWS credentials from environment
|
509
|
+
variables or the AWS metadata service. This version improves on that by
|
510
|
+
using the boto3 library itself (if available), which uses the entire range
|
511
|
+
of implicit authentication features packed into it.
|
512
|
+
|
513
|
+
Without this improvement, `sts.AssumeRoleWithWebIdentity` authentication is
|
514
|
+
not supported for EKS pods and the EC2 attached role credentials are
|
515
|
+
used instead (see: https://medium.com/@derek10cloud/gcp-workload-identity-federation-doesnt-yet-support-eks-irsa-in-aws-a3c71877671a).
|
516
|
+
"""
|
517
|
+
|
518
|
+
def get_aws_security_credentials(
|
519
|
+
self, context: Any, request: Any
|
520
|
+
) -> gcp_aws.AwsSecurityCredentials:
|
521
|
+
"""Get the security credentials from the local environment.
|
522
|
+
|
523
|
+
This method is a copy of the original method from the
|
524
|
+
`google.auth.aws._DefaultAwsSecurityCredentialsSupplier` class. It has
|
525
|
+
been modified to use the boto3 library to extract the AWS credentials
|
526
|
+
from the local environment.
|
527
|
+
|
528
|
+
Args:
|
529
|
+
context: The context to use to get the security credentials.
|
530
|
+
request: The request to use to get the security credentials.
|
531
|
+
|
532
|
+
Returns:
|
533
|
+
The AWS temporary security credentials.
|
534
|
+
"""
|
535
|
+
try:
|
536
|
+
import boto3
|
537
|
+
|
538
|
+
session = boto3.Session()
|
539
|
+
credentials = session.get_credentials()
|
540
|
+
if credentials is not None:
|
541
|
+
creds = credentials.get_frozen_credentials()
|
542
|
+
return gcp_aws.AwsSecurityCredentials(
|
543
|
+
creds.access_key,
|
544
|
+
creds.secret_key,
|
545
|
+
creds.token,
|
546
|
+
)
|
547
|
+
except ImportError:
|
548
|
+
pass
|
549
|
+
|
550
|
+
logger.debug(
|
551
|
+
"Failed to extract AWS credentials from the local environment "
|
552
|
+
"using the boto3 library. Falling back to the original "
|
553
|
+
"implementation."
|
554
|
+
)
|
555
|
+
|
556
|
+
return super().get_aws_security_credentials(context, request)
|
557
|
+
|
558
|
+
def get_aws_region(self, context: Any, request: Any) -> str:
|
559
|
+
"""Get the AWS region from the local environment.
|
560
|
+
|
561
|
+
This method is a copy of the original method from the
|
562
|
+
`google.auth.aws._DefaultAwsSecurityCredentialsSupplier` class. It has
|
563
|
+
been modified to use the boto3 library to extract the AWS
|
564
|
+
region from the local environment.
|
565
|
+
|
566
|
+
Args:
|
567
|
+
context: The context to use to get the security credentials.
|
568
|
+
request: The request to use to get the security credentials.
|
569
|
+
|
570
|
+
Returns:
|
571
|
+
The AWS region.
|
572
|
+
"""
|
573
|
+
try:
|
574
|
+
import boto3
|
575
|
+
|
576
|
+
session = boto3.Session()
|
577
|
+
if session.region_name:
|
578
|
+
return session.region_name # type: ignore[no-any-return]
|
579
|
+
except ImportError:
|
580
|
+
pass
|
581
|
+
|
582
|
+
logger.debug(
|
583
|
+
"Failed to extract AWS region from the local environment "
|
584
|
+
"using the boto3 library. Falling back to the original "
|
585
|
+
"implementation."
|
586
|
+
)
|
587
|
+
|
588
|
+
return super().get_aws_region( # type: ignore[no-any-return]
|
589
|
+
context, request
|
590
|
+
)
|
591
|
+
|
592
|
+
except ImportError:
|
593
|
+
# The `google.auth.aws._DefaultAwsSecurityCredentialsSupplier`
|
594
|
+
# class has been introduced in the `google-auth` library version 2.29.0.
|
595
|
+
# Before that, the AWS logic was part of the `google.auth.awsCredentials`
|
596
|
+
# class itself.
|
597
|
+
ZenMLAwsSecurityCredentialsSupplier = None # type: ignore[assignment,misc]
|
598
|
+
pass
|
599
|
+
|
600
|
+
|
499
601
|
class ZenMLGCPAWSExternalAccountCredentials(gcp_aws.Credentials): # type: ignore[misc]
|
500
602
|
"""An improved version of the GCP external account credential for AWS.
|
501
603
|
|
@@ -508,6 +610,13 @@ class ZenMLGCPAWSExternalAccountCredentials(gcp_aws.Credentials): # type: ignor
|
|
508
610
|
Without this improvement, `sts.AssumeRoleWithWebIdentity` authentication is
|
509
611
|
not supported for EKS pods and the EC2 attached role credentials are
|
510
612
|
used instead (see: https://medium.com/@derek10cloud/gcp-workload-identity-federation-doesnt-yet-support-eks-irsa-in-aws-a3c71877671a).
|
613
|
+
|
614
|
+
IMPORTANT: subclassing this class only works with the `google-auth` library
|
615
|
+
version lower than 2.29.0. Starting from version 2.29.0, the AWS logic
|
616
|
+
has been moved to a separate `google.auth.aws._DefaultAwsSecurityCredentialsSupplier`
|
617
|
+
class that can be subclassed instead and supplied as the
|
618
|
+
`aws_security_credentials_supplier` parameter to the
|
619
|
+
`google.auth.aws.Credentials` class.
|
511
620
|
"""
|
512
621
|
|
513
622
|
def _get_security_credentials(
|
@@ -539,12 +648,14 @@ class ZenMLGCPAWSExternalAccountCredentials(gcp_aws.Credentials): # type: ignor
|
|
539
648
|
"secret_access_key": creds.secret_key,
|
540
649
|
"security_token": creds.token,
|
541
650
|
}
|
542
|
-
except
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
651
|
+
except ImportError:
|
652
|
+
pass
|
653
|
+
|
654
|
+
logger.debug(
|
655
|
+
"Failed to extract AWS credentials from the local environment "
|
656
|
+
"using the boto3 library. Falling back to the original "
|
657
|
+
"implementation."
|
658
|
+
)
|
548
659
|
|
549
660
|
return super()._get_security_credentials( # type: ignore[no-any-return]
|
550
661
|
request, imdsv2_session_token
|
@@ -1126,6 +1237,12 @@ class GCPServiceConnector(ServiceConnector):
|
|
1126
1237
|
account_info.get("subject_token_type")
|
1127
1238
|
== _AWS_SUBJECT_TOKEN_TYPE
|
1128
1239
|
):
|
1240
|
+
if ZenMLAwsSecurityCredentialsSupplier is not None:
|
1241
|
+
account_info["aws_security_credentials_supplier"] = (
|
1242
|
+
ZenMLAwsSecurityCredentialsSupplier(
|
1243
|
+
account_info.pop("credential_source"),
|
1244
|
+
)
|
1245
|
+
)
|
1129
1246
|
credentials = (
|
1130
1247
|
ZenMLGCPAWSExternalAccountCredentials.from_info(
|
1131
1248
|
account_info,
|
@@ -295,7 +295,7 @@ class KanikoImageBuilder(BaseImageBuilder):
|
|
295
295
|
logger.debug("Writing build context to process stdin.")
|
296
296
|
assert process.stdin
|
297
297
|
with process.stdin as _, tempfile.TemporaryFile(mode="w+b") as f:
|
298
|
-
build_context.write_archive(f,
|
298
|
+
build_context.write_archive(f, use_gzip=True)
|
299
299
|
while True:
|
300
300
|
data = f.read(1024)
|
301
301
|
if not data:
|
@@ -57,6 +57,7 @@ DATABRICKS_HOST = "DATABRICKS_HOST"
|
|
57
57
|
DATABRICKS_USERNAME = "DATABRICKS_USERNAME"
|
58
58
|
DATABRICKS_PASSWORD = "DATABRICKS_PASSWORD"
|
59
59
|
DATABRICKS_TOKEN = "DATABRICKS_TOKEN"
|
60
|
+
DATABRICKS_UNITY_CATALOG = "databricks-uc"
|
60
61
|
|
61
62
|
|
62
63
|
class MLFlowExperimentTracker(BaseExperimentTracker):
|
@@ -285,7 +286,6 @@ class MLFlowExperimentTracker(BaseExperimentTracker):
|
|
285
286
|
"""Configures the MLflow tracking URI and any additional credentials."""
|
286
287
|
tracking_uri = self.get_tracking_uri()
|
287
288
|
mlflow.set_tracking_uri(tracking_uri)
|
288
|
-
mlflow.set_registry_uri(tracking_uri)
|
289
289
|
|
290
290
|
if is_databricks_tracking_uri(tracking_uri):
|
291
291
|
if self.config.databricks_host:
|
@@ -296,6 +296,8 @@ class MLFlowExperimentTracker(BaseExperimentTracker):
|
|
296
296
|
os.environ[DATABRICKS_PASSWORD] = self.config.tracking_password
|
297
297
|
if self.config.tracking_token:
|
298
298
|
os.environ[DATABRICKS_TOKEN] = self.config.tracking_token
|
299
|
+
if self.config.enable_unity_catalog:
|
300
|
+
mlflow.set_registry_uri(DATABRICKS_UNITY_CATALOG)
|
299
301
|
else:
|
300
302
|
os.environ[MLFLOW_TRACKING_URI] = tracking_uri
|
301
303
|
if self.config.tracking_username:
|
@@ -98,6 +98,8 @@ class MLFlowExperimentTrackerConfig(
|
|
98
98
|
databricks_host: The host of the Databricks workspace with the MLflow
|
99
99
|
managed server to connect to. This is only required if
|
100
100
|
`tracking_uri` value is set to `"databricks"`.
|
101
|
+
enable_unity_catalog: If `True`, will enable the Databricks Unity Catalog for
|
102
|
+
logging and registering models.
|
101
103
|
"""
|
102
104
|
|
103
105
|
tracking_uri: Optional[str] = None
|
@@ -106,6 +108,7 @@ class MLFlowExperimentTrackerConfig(
|
|
106
108
|
tracking_token: Optional[str] = SecretField(default=None)
|
107
109
|
tracking_insecure_tls: bool = False
|
108
110
|
databricks_host: Optional[str] = None
|
111
|
+
enable_unity_catalog: bool = False
|
109
112
|
|
110
113
|
@model_validator(mode="after")
|
111
114
|
def _ensure_authentication_if_necessary(
|
zenml/logger.py
CHANGED
@@ -46,6 +46,7 @@ class CustomFormatter(logging.Formatter):
|
|
46
46
|
cyan: str = "\x1b[1;36m"
|
47
47
|
bold_red: str = "\x1b[31;1m"
|
48
48
|
purple: str = "\x1b[1;35m"
|
49
|
+
blue: str = "\x1b[34m"
|
49
50
|
reset: str = "\x1b[0m"
|
50
51
|
|
51
52
|
format_template: str = (
|
@@ -94,6 +95,18 @@ class CustomFormatter(logging.Formatter):
|
|
94
95
|
+ quoted
|
95
96
|
+ self.COLORS.get(LoggingLevels(record.levelno)),
|
96
97
|
)
|
98
|
+
|
99
|
+
# Format URLs
|
100
|
+
url_pattern = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
|
101
|
+
urls = re.findall(url_pattern, formatted_message)
|
102
|
+
for url in urls:
|
103
|
+
formatted_message = formatted_message.replace(
|
104
|
+
url,
|
105
|
+
self.reset
|
106
|
+
+ self.blue
|
107
|
+
+ url
|
108
|
+
+ self.COLORS.get(LoggingLevels(record.levelno)),
|
109
|
+
)
|
97
110
|
return formatted_message
|
98
111
|
|
99
112
|
|
zenml/models/__init__.py
CHANGED
@@ -362,13 +362,6 @@ from zenml.models.v2.core.event_source import (
|
|
362
362
|
from zenml.models.v2.misc.user_auth import UserAuthModel
|
363
363
|
from zenml.models.v2.misc.build_item import BuildItem
|
364
364
|
from zenml.models.v2.misc.loaded_visualization import LoadedVisualization
|
365
|
-
from zenml.models.v2.misc.hub_plugin_models import (
|
366
|
-
HubPluginRequestModel,
|
367
|
-
HubPluginResponseModel,
|
368
|
-
HubUserResponseModel,
|
369
|
-
HubPluginBaseModel,
|
370
|
-
PluginStatus,
|
371
|
-
)
|
372
365
|
from zenml.models.v2.misc.external_user import ExternalUserModel
|
373
366
|
from zenml.models.v2.misc.auth_models import (
|
374
367
|
OAuthDeviceAuthorizationRequest,
|
@@ -735,11 +728,6 @@ __all__ = [
|
|
735
728
|
"ExternalUserModel",
|
736
729
|
"BuildItem",
|
737
730
|
"LoadedVisualization",
|
738
|
-
"HubPluginRequestModel",
|
739
|
-
"HubPluginResponseModel",
|
740
|
-
"HubUserResponseModel",
|
741
|
-
"HubPluginBaseModel",
|
742
|
-
"PluginStatus",
|
743
731
|
"ServerModel",
|
744
732
|
"ServerDatabaseType",
|
745
733
|
"ServerDeploymentType",
|
@@ -18,7 +18,6 @@ from uuid import UUID
|
|
18
18
|
|
19
19
|
from pydantic import Field
|
20
20
|
|
21
|
-
from zenml.config.docker_settings import SourceFileMode
|
22
21
|
from zenml.config.pipeline_configurations import PipelineConfiguration
|
23
22
|
from zenml.config.pipeline_spec import PipelineSpec
|
24
23
|
from zenml.config.step_configurations import Step
|
@@ -82,26 +81,14 @@ class PipelineDeploymentBase(BaseZenModel):
|
|
82
81
|
)
|
83
82
|
|
84
83
|
@property
|
85
|
-
def
|
86
|
-
"""Whether the deployment
|
84
|
+
def should_prevent_build_reuse(self) -> bool:
|
85
|
+
"""Whether the deployment prevents a build reuse.
|
87
86
|
|
88
87
|
Returns:
|
89
|
-
Whether the deployment
|
88
|
+
Whether the deployment prevents a build reuse.
|
90
89
|
"""
|
91
90
|
return any(
|
92
|
-
step.config.docker_settings.
|
93
|
-
for step in self.step_configurations.values()
|
94
|
-
)
|
95
|
-
|
96
|
-
@property
|
97
|
-
def requires_code_download(self) -> bool:
|
98
|
-
"""Whether the deployment requires downloading some code files.
|
99
|
-
|
100
|
-
Returns:
|
101
|
-
Whether the deployment requires downloading some code files.
|
102
|
-
"""
|
103
|
-
return any(
|
104
|
-
step.config.docker_settings.source_files == SourceFileMode.DOWNLOAD
|
91
|
+
step.config.docker_settings.prevent_build_reuse
|
105
92
|
for step in self.step_configurations.values()
|
106
93
|
)
|
107
94
|
|
@@ -125,6 +112,10 @@ class PipelineDeploymentRequest(
|
|
125
112
|
default=None,
|
126
113
|
title="The code reference associated with the deployment.",
|
127
114
|
)
|
115
|
+
code_path: Optional[str] = Field(
|
116
|
+
default=None,
|
117
|
+
title="Optional path where the code is stored in the artifact store.",
|
118
|
+
)
|
128
119
|
template: Optional[UUID] = Field(
|
129
120
|
default=None,
|
130
121
|
description="Template used for the deployment.",
|
@@ -169,6 +160,10 @@ class PipelineDeploymentResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
169
160
|
pipeline_spec: Optional[PipelineSpec] = Field(
|
170
161
|
default=None, title="The pipeline spec of the deployment."
|
171
162
|
)
|
163
|
+
code_path: Optional[str] = Field(
|
164
|
+
default=None,
|
165
|
+
title="Optional path where the code is stored in the artifact store.",
|
166
|
+
)
|
172
167
|
|
173
168
|
pipeline: Optional[PipelineResponse] = Field(
|
174
169
|
default=None, title="The pipeline associated with the deployment."
|
@@ -293,6 +288,15 @@ class PipelineDeploymentResponse(
|
|
293
288
|
"""
|
294
289
|
return self.get_metadata().pipeline_spec
|
295
290
|
|
291
|
+
@property
|
292
|
+
def code_path(self) -> Optional[str]:
|
293
|
+
"""The `code_path` property.
|
294
|
+
|
295
|
+
Returns:
|
296
|
+
the value of the property.
|
297
|
+
"""
|
298
|
+
return self.get_metadata().code_path
|
299
|
+
|
296
300
|
@property
|
297
301
|
def pipeline(self) -> Optional[PipelineResponse]:
|
298
302
|
"""The `pipeline` property.
|
@@ -347,18 +351,6 @@ class PipelineDeploymentResponse(
|
|
347
351
|
"""
|
348
352
|
return self.get_metadata().template_id
|
349
353
|
|
350
|
-
@property
|
351
|
-
def requires_code_download(self) -> bool:
|
352
|
-
"""Whether the deployment requires downloading some code files.
|
353
|
-
|
354
|
-
Returns:
|
355
|
-
Whether the deployment requires downloading some code files.
|
356
|
-
"""
|
357
|
-
return any(
|
358
|
-
step.config.docker_settings.source_files == SourceFileMode.DOWNLOAD
|
359
|
-
for step in self.step_configurations.values()
|
360
|
-
)
|
361
|
-
|
362
354
|
|
363
355
|
# ------------------ Filter Model ------------------
|
364
356
|
|
@@ -206,6 +206,10 @@ class PipelineRunResponseMetadata(WorkspaceScopedResponseMetadata):
|
|
206
206
|
max_length=STR_FIELD_MAX_LENGTH,
|
207
207
|
default=None,
|
208
208
|
)
|
209
|
+
code_path: Optional[str] = Field(
|
210
|
+
default=None,
|
211
|
+
title="Optional path where the code is stored in the artifact store.",
|
212
|
+
)
|
209
213
|
template_id: Optional[UUID] = Field(
|
210
214
|
default=None,
|
211
215
|
description="Template used for the pipeline run.",
|
@@ -425,6 +429,15 @@ class PipelineRunResponse(
|
|
425
429
|
"""
|
426
430
|
return self.get_metadata().orchestrator_run_id
|
427
431
|
|
432
|
+
@property
|
433
|
+
def code_path(self) -> Optional[str]:
|
434
|
+
"""The `code_path` property.
|
435
|
+
|
436
|
+
Returns:
|
437
|
+
the value of the property.
|
438
|
+
"""
|
439
|
+
return self.get_metadata().code_path
|
440
|
+
|
428
441
|
@property
|
429
442
|
def template_id(self) -> Optional[UUID]:
|
430
443
|
"""The `template_id` property.
|
@@ -82,6 +82,9 @@ class ServerSettingsResponseBody(BaseResponseBody):
|
|
82
82
|
display_updates: Optional[bool] = Field(
|
83
83
|
title="Whether to display notifications about ZenML updates in the dashboard.",
|
84
84
|
)
|
85
|
+
last_user_activity: datetime = Field(
|
86
|
+
title="The timestamp when the last user activity was detected.",
|
87
|
+
)
|
85
88
|
updated: datetime = Field(
|
86
89
|
title="The timestamp when this resource was last updated."
|
87
90
|
)
|
@@ -179,6 +182,15 @@ class ServerSettingsResponse(
|
|
179
182
|
"""
|
180
183
|
return self.get_body().active
|
181
184
|
|
185
|
+
@property
|
186
|
+
def last_user_activity(self) -> datetime:
|
187
|
+
"""The `last_user_activity` property.
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
the value of the property.
|
191
|
+
"""
|
192
|
+
return self.get_body().last_user_activity
|
193
|
+
|
182
194
|
@property
|
183
195
|
def updated(self) -> datetime:
|
184
196
|
"""The `updated` property.
|
zenml/models/v2/core/user.py
CHANGED
@@ -65,12 +65,6 @@ class UserBase(BaseModel):
|
|
65
65
|
description="`null` if not answered, `true` if agreed, "
|
66
66
|
"`false` if skipped.",
|
67
67
|
)
|
68
|
-
hub_token: Optional[str] = Field(
|
69
|
-
default=None,
|
70
|
-
title="JWT Token for the connected Hub account. Only relevant for user "
|
71
|
-
"accounts.",
|
72
|
-
max_length=STR_FIELD_MAX_LENGTH,
|
73
|
-
)
|
74
68
|
password: Optional[str] = Field(
|
75
69
|
default=None,
|
76
70
|
title="A password for the user.",
|
@@ -296,12 +290,6 @@ class UserResponseMetadata(BaseResponseMetadata):
|
|
296
290
|
"for user accounts.",
|
297
291
|
max_length=STR_FIELD_MAX_LENGTH,
|
298
292
|
)
|
299
|
-
hub_token: Optional[str] = Field(
|
300
|
-
default=None,
|
301
|
-
title="JWT Token for the connected Hub account. Only relevant for user "
|
302
|
-
"accounts.",
|
303
|
-
max_length=STR_FIELD_MAX_LENGTH,
|
304
|
-
)
|
305
293
|
external_user_id: Optional[UUID] = Field(
|
306
294
|
default=None,
|
307
295
|
title="The external user ID associated with the account. Only relevant "
|
@@ -416,15 +404,6 @@ class UserResponse(
|
|
416
404
|
"""
|
417
405
|
return self.get_metadata().email
|
418
406
|
|
419
|
-
@property
|
420
|
-
def hub_token(self) -> Optional[str]:
|
421
|
-
"""The `hub_token` property.
|
422
|
-
|
423
|
-
Returns:
|
424
|
-
the value of the property.
|
425
|
-
"""
|
426
|
-
return self.get_metadata().hub_token
|
427
|
-
|
428
407
|
@property
|
429
408
|
def external_user_id(self) -> Optional[UUID]:
|
430
409
|
"""The `external_user_id` property.
|
@@ -13,7 +13,8 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Model definitions for ZenML servers."""
|
15
15
|
|
16
|
-
from
|
16
|
+
from datetime import datetime
|
17
|
+
from typing import Dict, Optional
|
17
18
|
from uuid import UUID, uuid4
|
18
19
|
|
19
20
|
from pydantic import BaseModel, Field
|
@@ -103,6 +104,11 @@ class ServerModel(BaseModel):
|
|
103
104
|
title="Flag to indicate whether the server is using the legacy dashboard.",
|
104
105
|
)
|
105
106
|
|
107
|
+
last_user_activity: Optional[datetime] = Field(
|
108
|
+
None,
|
109
|
+
title="Timestamp of latest user activity traced on the server.",
|
110
|
+
)
|
111
|
+
|
106
112
|
def is_local(self) -> bool:
|
107
113
|
"""Return whether the server is running locally.
|
108
114
|
|
@@ -73,13 +73,6 @@ class UserAuthModel(BaseZenModel):
|
|
73
73
|
"`false` if skipped.",
|
74
74
|
)
|
75
75
|
|
76
|
-
hub_token: Optional[str] = Field(
|
77
|
-
default=None,
|
78
|
-
title="JWT Token for the connected Hub account. Only relevant for user "
|
79
|
-
"accounts.",
|
80
|
-
max_length=STR_FIELD_MAX_LENGTH,
|
81
|
-
)
|
82
|
-
|
83
76
|
@classmethod
|
84
77
|
def _get_crypt_context(cls) -> "CryptContext":
|
85
78
|
"""Returns the password encryption context.
|