zenml-nightly 0.83.1.dev20250624__py3-none-any.whl → 0.83.1.dev20250626__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.
- zenml/VERSION +1 -1
- zenml/cli/base.py +3 -2
- zenml/cli/login.py +21 -3
- zenml/cli/service_connectors.py +5 -12
- zenml/cli/stack.py +1 -5
- zenml/cli/utils.py +8 -52
- zenml/client.py +32 -40
- zenml/config/__init__.py +13 -2
- zenml/constants.py +0 -1
- zenml/exceptions.py +16 -0
- zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +15 -6
- zenml/integrations/aws/container_registries/aws_container_registry.py +3 -1
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +54 -58
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +28 -19
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +19 -63
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +8 -3
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +36 -61
- zenml/integrations/hyperai/orchestrators/hyperai_orchestrator.py +19 -22
- zenml/integrations/integration.py +23 -58
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +28 -31
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +33 -20
- zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +25 -100
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +19 -8
- zenml/integrations/skypilot/utils.py +17 -13
- zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +28 -12
- zenml/models/__init__.py +2 -0
- zenml/models/v2/core/service_connector.py +178 -108
- zenml/models/v2/core/step_run.py +1 -0
- zenml/orchestrators/__init__.py +2 -0
- zenml/orchestrators/base_orchestrator.py +137 -66
- zenml/orchestrators/input_utils.py +5 -13
- zenml/orchestrators/local/local_orchestrator.py +19 -9
- zenml/orchestrators/local_docker/local_docker_orchestrator.py +15 -5
- zenml/orchestrators/publish_utils.py +24 -0
- zenml/orchestrators/step_run_utils.py +1 -2
- zenml/pipelines/run_utils.py +12 -7
- zenml/service_connectors/service_connector.py +11 -61
- zenml/service_connectors/service_connector_utils.py +4 -2
- zenml/step_operators/step_operator_entrypoint_configuration.py +1 -1
- zenml/utils/package_utils.py +111 -1
- zenml/zen_server/routers/service_connectors_endpoints.py +7 -22
- zenml/zen_stores/migrations/versions/5bb25e95849c_add_internal_secrets.py +62 -0
- zenml/zen_stores/rest_zen_store.py +204 -132
- zenml/zen_stores/schemas/secret_schemas.py +5 -0
- zenml/zen_stores/schemas/service_connector_schemas.py +16 -14
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +4 -1
- zenml/zen_stores/sql_zen_store.py +241 -119
- zenml/zen_stores/zen_store_interface.py +9 -1
- {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/METADATA +1 -1
- {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/RECORD +53 -53
- zenml/utils/integration_utils.py +0 -34
- {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/entry_points.txt +0 -0
zenml/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.83.1.
|
1
|
+
0.83.1.dev20250626
|
zenml/cli/base.py
CHANGED
@@ -49,6 +49,7 @@ from zenml.integrations.registry import integration_registry
|
|
49
49
|
from zenml.io import fileio
|
50
50
|
from zenml.logger import get_logger
|
51
51
|
from zenml.utils.io_utils import copy_dir, get_global_config_directory
|
52
|
+
from zenml.utils.package_utils import get_package_information
|
52
53
|
from zenml.utils.server_utils import get_local_server
|
53
54
|
from zenml.utils.yaml_utils import write_yaml
|
54
55
|
|
@@ -640,7 +641,7 @@ def info(
|
|
640
641
|
}
|
641
642
|
|
642
643
|
if all:
|
643
|
-
user_info["packages"] =
|
644
|
+
user_info["packages"] = get_package_information()
|
644
645
|
if packages:
|
645
646
|
if user_info.get("packages"):
|
646
647
|
if isinstance(user_info["packages"], dict):
|
@@ -650,7 +651,7 @@ def info(
|
|
650
651
|
if p in packages
|
651
652
|
}
|
652
653
|
else:
|
653
|
-
user_info["query_packages"] =
|
654
|
+
user_info["query_packages"] = get_package_information(
|
654
655
|
list(packages)
|
655
656
|
)
|
656
657
|
if file:
|
zenml/cli/login.py
CHANGED
@@ -229,6 +229,7 @@ def connect_to_pro_server(
|
|
229
229
|
api_key: Optional[str] = None,
|
230
230
|
refresh: bool = False,
|
231
231
|
pro_api_url: Optional[str] = None,
|
232
|
+
verify_ssl: Union[str, bool] = True,
|
232
233
|
) -> None:
|
233
234
|
"""Connect the client to a ZenML Pro server.
|
234
235
|
|
@@ -238,6 +239,8 @@ def connect_to_pro_server(
|
|
238
239
|
api_key: The API key to use to authenticate with the ZenML Pro server.
|
239
240
|
refresh: Whether to force a new login flow with the ZenML Pro server.
|
240
241
|
pro_api_url: The URL for the ZenML Pro API.
|
242
|
+
verify_ssl: Whether to verify the server's TLS certificate. If a string
|
243
|
+
is passed, it is interpreted as the path to a CA bundle file.
|
241
244
|
|
242
245
|
Raises:
|
243
246
|
ValueError: If incorrect parameters are provided.
|
@@ -280,7 +283,12 @@ def connect_to_pro_server(
|
|
280
283
|
# server to connect to.
|
281
284
|
if api_key:
|
282
285
|
if server_url:
|
283
|
-
connect_to_server(
|
286
|
+
connect_to_server(
|
287
|
+
server_url,
|
288
|
+
api_key=api_key,
|
289
|
+
pro_server=True,
|
290
|
+
verify_ssl=verify_ssl,
|
291
|
+
)
|
284
292
|
return
|
285
293
|
else:
|
286
294
|
raise ValueError(
|
@@ -299,6 +307,7 @@ def connect_to_pro_server(
|
|
299
307
|
try:
|
300
308
|
token = web_login(
|
301
309
|
pro_api_url=pro_api_url,
|
310
|
+
verify_ssl=verify_ssl,
|
302
311
|
)
|
303
312
|
except AuthorizationException as e:
|
304
313
|
cli_utils.error(f"Authorization error: {e}")
|
@@ -418,7 +427,9 @@ def connect_to_pro_server(
|
|
418
427
|
f"Connecting to ZenML Pro server: {server.name} [{str(server.id)}] "
|
419
428
|
)
|
420
429
|
|
421
|
-
connect_to_server(
|
430
|
+
connect_to_server(
|
431
|
+
server.url, api_key=api_key, pro_server=True, verify_ssl=verify_ssl
|
432
|
+
)
|
422
433
|
|
423
434
|
# Update the stored server info with more accurate data taken from the
|
424
435
|
# ZenML Pro workspace object.
|
@@ -555,7 +566,7 @@ def _fail_if_authentication_environment_variables_set() -> None:
|
|
555
566
|
not return until the server exits or is stopped with CTRL+C
|
556
567
|
|
557
568
|
* `--docker`: start the local ZenML server as a Docker container instead
|
558
|
-
of a local process
|
569
|
+
of a local background process.
|
559
570
|
|
560
571
|
* `--port`: use a custom TCP port value for the local ZenML server
|
561
572
|
|
@@ -775,6 +786,9 @@ def login(
|
|
775
786
|
pro_server=server,
|
776
787
|
refresh=True,
|
777
788
|
pro_api_url=pro_api_url,
|
789
|
+
verify_ssl=ssl_ca_cert
|
790
|
+
if ssl_ca_cert is not None
|
791
|
+
else not no_verify_ssl,
|
778
792
|
)
|
779
793
|
return
|
780
794
|
|
@@ -822,6 +836,7 @@ def login(
|
|
822
836
|
# Prefer the pro API URL extracted from the server info if
|
823
837
|
# available
|
824
838
|
pro_api_url=server_pro_api_url or pro_api_url,
|
839
|
+
verify_ssl=verify_ssl,
|
825
840
|
)
|
826
841
|
else:
|
827
842
|
connect_to_server(
|
@@ -837,6 +852,7 @@ def login(
|
|
837
852
|
api_key=api_key_value,
|
838
853
|
refresh=refresh,
|
839
854
|
pro_api_url=pro_api_url,
|
855
|
+
verify_ssl=verify_ssl,
|
840
856
|
)
|
841
857
|
|
842
858
|
elif current_non_local_server and not refresh:
|
@@ -861,6 +877,7 @@ def login(
|
|
861
877
|
# Prefer the pro API URL extracted from the server info if
|
862
878
|
# available
|
863
879
|
pro_api_url=server_pro_api_url or pro_api_url,
|
880
|
+
verify_ssl=verify_ssl,
|
864
881
|
)
|
865
882
|
else:
|
866
883
|
cli_utils.declare(
|
@@ -890,6 +907,7 @@ def login(
|
|
890
907
|
connect_to_pro_server(
|
891
908
|
api_key=api_key_value,
|
892
909
|
pro_api_url=pro_api_url,
|
910
|
+
verify_ssl=verify_ssl,
|
893
911
|
)
|
894
912
|
|
895
913
|
|
zenml/cli/service_connectors.py
CHANGED
@@ -899,14 +899,7 @@ def register_service_connector(
|
|
899
899
|
|
900
900
|
# Prepare the rest of the variables to fall through to the
|
901
901
|
# non-interactive configuration case
|
902
|
-
parsed_args = connector_model.configuration
|
903
|
-
parsed_args.update(
|
904
|
-
{
|
905
|
-
k: s.get_secret_value()
|
906
|
-
for k, s in connector_model.secrets.items()
|
907
|
-
if s is not None
|
908
|
-
}
|
909
|
-
)
|
902
|
+
parsed_args = connector_model.configuration.plain
|
910
903
|
auto_configure = False
|
911
904
|
no_verify = False
|
912
905
|
expiration_seconds = connector_model.expiration_seconds
|
@@ -1137,7 +1130,7 @@ def describe_service_connector(
|
|
1137
1130
|
try:
|
1138
1131
|
connector = client.get_service_connector(
|
1139
1132
|
name_id_or_prefix=name_id_or_prefix,
|
1140
|
-
|
1133
|
+
expand_secrets=show_secrets,
|
1141
1134
|
)
|
1142
1135
|
except KeyError as err:
|
1143
1136
|
cli_utils.error(str(err))
|
@@ -1385,7 +1378,7 @@ def update_service_connector(
|
|
1385
1378
|
connector = client.get_service_connector(
|
1386
1379
|
name_id_or_prefix,
|
1387
1380
|
allow_name_prefix_match=False,
|
1388
|
-
|
1381
|
+
expand_secrets=True,
|
1389
1382
|
)
|
1390
1383
|
except KeyError as e:
|
1391
1384
|
cli_utils.error(str(e))
|
@@ -1445,7 +1438,7 @@ def update_service_connector(
|
|
1445
1438
|
default=False,
|
1446
1439
|
)
|
1447
1440
|
|
1448
|
-
existing_config = connector.
|
1441
|
+
existing_config = connector.configuration.plain
|
1449
1442
|
|
1450
1443
|
if confirm:
|
1451
1444
|
# Here we reconfigure the connector or update the existing
|
@@ -1582,7 +1575,7 @@ def update_service_connector(
|
|
1582
1575
|
# Non-interactive configuration
|
1583
1576
|
|
1584
1577
|
# Apply the configuration from the command line arguments
|
1585
|
-
config_dict = connector.
|
1578
|
+
config_dict = connector.configuration.plain
|
1586
1579
|
config_dict.update(parsed_args)
|
1587
1580
|
|
1588
1581
|
if not resource_type and not connector.is_multi_type:
|
zenml/cli/stack.py
CHANGED
@@ -1783,14 +1783,10 @@ def _get_service_connector_info(
|
|
1783
1783
|
answers = {}
|
1784
1784
|
for req_field in required_fields:
|
1785
1785
|
if connector_details:
|
1786
|
-
if conf_value := connector_details.configuration.
|
1786
|
+
if conf_value := connector_details.configuration.get_plain(
|
1787
1787
|
req_field, None
|
1788
1788
|
):
|
1789
1789
|
answers[req_field] = conf_value
|
1790
|
-
elif secret_value := connector_details.secrets.get(
|
1791
|
-
req_field, None
|
1792
|
-
):
|
1793
|
-
answers[req_field] = secret_value.get_secret_value()
|
1794
1790
|
if req_field not in answers:
|
1795
1791
|
answers[req_field] = Prompt.ask(
|
1796
1792
|
f"Please enter value for `{req_field}`:",
|
zenml/cli/utils.py
CHANGED
@@ -40,7 +40,6 @@ from typing import (
|
|
40
40
|
)
|
41
41
|
|
42
42
|
import click
|
43
|
-
import pkg_resources
|
44
43
|
import yaml
|
45
44
|
from pydantic import BaseModel, SecretStr
|
46
45
|
from rich import box, table
|
@@ -80,6 +79,7 @@ from zenml.stack import StackComponent
|
|
80
79
|
from zenml.stack.flavor import Flavor
|
81
80
|
from zenml.stack.stack_component import StackComponentConfig
|
82
81
|
from zenml.utils import secret_utils
|
82
|
+
from zenml.utils.package_utils import requirement_installed
|
83
83
|
from zenml.utils.time_utils import expires_in
|
84
84
|
from zenml.utils.typing_utils import get_origin, is_union
|
85
85
|
|
@@ -1052,7 +1052,7 @@ def install_packages(
|
|
1052
1052
|
# just return without doing anything
|
1053
1053
|
return
|
1054
1054
|
|
1055
|
-
if use_uv and not
|
1055
|
+
if use_uv and not requirement_installed("uv"):
|
1056
1056
|
# If uv is installed globally, don't run as a python module
|
1057
1057
|
command = []
|
1058
1058
|
else:
|
@@ -1094,7 +1094,7 @@ def uninstall_package(package: str, use_uv: bool = False) -> None:
|
|
1094
1094
|
package: The package to uninstall.
|
1095
1095
|
use_uv: Whether to use uv for package uninstallation.
|
1096
1096
|
"""
|
1097
|
-
if use_uv and not
|
1097
|
+
if use_uv and not requirement_installed("uv"):
|
1098
1098
|
# If uv is installed globally, don't run as a python module
|
1099
1099
|
command = []
|
1100
1100
|
else:
|
@@ -1110,22 +1110,6 @@ def uninstall_package(package: str, use_uv: bool = False) -> None:
|
|
1110
1110
|
subprocess.check_call(command)
|
1111
1111
|
|
1112
1112
|
|
1113
|
-
def is_installed_in_python_environment(package: str) -> bool:
|
1114
|
-
"""Check if a package is installed in the current python environment.
|
1115
|
-
|
1116
|
-
Args:
|
1117
|
-
package: The package to check.
|
1118
|
-
|
1119
|
-
Returns:
|
1120
|
-
True if the package is installed, False otherwise.
|
1121
|
-
"""
|
1122
|
-
try:
|
1123
|
-
pkg_resources.get_distribution(package)
|
1124
|
-
return True
|
1125
|
-
except pkg_resources.DistributionNotFound:
|
1126
|
-
return False
|
1127
|
-
|
1128
|
-
|
1129
1113
|
def is_uv_installed() -> bool:
|
1130
1114
|
"""Check if uv is installed.
|
1131
1115
|
|
@@ -1141,7 +1125,7 @@ def is_pip_installed() -> bool:
|
|
1141
1125
|
Returns:
|
1142
1126
|
True if pip is installed, False otherwise.
|
1143
1127
|
"""
|
1144
|
-
return
|
1128
|
+
return requirement_installed("pip")
|
1145
1129
|
|
1146
1130
|
|
1147
1131
|
def pretty_print_secret(
|
@@ -1830,7 +1814,7 @@ def print_service_connector_configuration(
|
|
1830
1814
|
|
1831
1815
|
console.print(rich_table)
|
1832
1816
|
|
1833
|
-
if len(connector.configuration) == 0
|
1817
|
+
if len(connector.configuration) == 0:
|
1834
1818
|
declare("No configuration options are set for this connector.")
|
1835
1819
|
|
1836
1820
|
else:
|
@@ -1842,8 +1826,8 @@ def print_service_connector_configuration(
|
|
1842
1826
|
rich_table.add_column("PROPERTY")
|
1843
1827
|
rich_table.add_column("VALUE", overflow="fold")
|
1844
1828
|
|
1845
|
-
config = connector.configuration.
|
1846
|
-
secrets = connector.secrets
|
1829
|
+
config = connector.configuration.non_secrets
|
1830
|
+
secrets = connector.configuration.secrets
|
1847
1831
|
for key, value in secrets.items():
|
1848
1832
|
if not show_secrets:
|
1849
1833
|
config[key] = "[HIDDEN]"
|
@@ -2499,30 +2483,6 @@ def temporary_active_stack(
|
|
2499
2483
|
Client().activate_stack(old_stack_id)
|
2500
2484
|
|
2501
2485
|
|
2502
|
-
def get_package_information(
|
2503
|
-
package_names: Optional[List[str]] = None,
|
2504
|
-
) -> Dict[str, str]:
|
2505
|
-
"""Get a dictionary of installed packages.
|
2506
|
-
|
2507
|
-
Args:
|
2508
|
-
package_names: Specific package names to get the information for.
|
2509
|
-
|
2510
|
-
Returns:
|
2511
|
-
A dictionary of the name:version for the package names passed in or
|
2512
|
-
all packages and their respective versions.
|
2513
|
-
"""
|
2514
|
-
import pkg_resources
|
2515
|
-
|
2516
|
-
if package_names:
|
2517
|
-
return {
|
2518
|
-
pkg.key: pkg.version
|
2519
|
-
for pkg in pkg_resources.working_set
|
2520
|
-
if pkg.key in package_names
|
2521
|
-
}
|
2522
|
-
|
2523
|
-
return {pkg.key: pkg.version for pkg in pkg_resources.working_set}
|
2524
|
-
|
2525
|
-
|
2526
2486
|
def print_user_info(info: Dict[str, Any]) -> None:
|
2527
2487
|
"""Print user information to the terminal.
|
2528
2488
|
|
@@ -2617,11 +2577,7 @@ def is_jupyter_installed() -> bool:
|
|
2617
2577
|
Returns:
|
2618
2578
|
bool: True if Jupyter notebook is installed, False otherwise.
|
2619
2579
|
"""
|
2620
|
-
|
2621
|
-
pkg_resources.get_distribution("notebook")
|
2622
|
-
return True
|
2623
|
-
except pkg_resources.DistributionNotFound:
|
2624
|
-
return False
|
2580
|
+
return requirement_installed("notebook")
|
2625
2581
|
|
2626
2582
|
|
2627
2583
|
def multi_choice_prompt(
|
zenml/client.py
CHANGED
@@ -5500,17 +5500,18 @@ class Client(metaclass=ClientMetaClass):
|
|
5500
5500
|
self,
|
5501
5501
|
name_id_or_prefix: Union[str, UUID],
|
5502
5502
|
allow_name_prefix_match: bool = True,
|
5503
|
-
load_secrets: bool = False,
|
5504
5503
|
hydrate: bool = True,
|
5504
|
+
expand_secrets: bool = False,
|
5505
5505
|
) -> ServiceConnectorResponse:
|
5506
5506
|
"""Fetches a registered service connector.
|
5507
5507
|
|
5508
5508
|
Args:
|
5509
5509
|
name_id_or_prefix: The id of the service connector to fetch.
|
5510
5510
|
allow_name_prefix_match: If True, allow matching by name prefix.
|
5511
|
-
load_secrets: If True, load the secrets for the service connector.
|
5512
5511
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
5513
5512
|
by including metadata fields in the response.
|
5513
|
+
expand_secrets: If True, expand the secrets for the service
|
5514
|
+
connector.
|
5514
5515
|
|
5515
5516
|
Returns:
|
5516
5517
|
The registered service connector.
|
@@ -5521,25 +5522,9 @@ class Client(metaclass=ClientMetaClass):
|
|
5521
5522
|
name_id_or_prefix=name_id_or_prefix,
|
5522
5523
|
allow_name_prefix_match=allow_name_prefix_match,
|
5523
5524
|
hydrate=hydrate,
|
5525
|
+
expand_secrets=expand_secrets,
|
5524
5526
|
)
|
5525
5527
|
|
5526
|
-
if load_secrets and connector.secret_id:
|
5527
|
-
client = Client()
|
5528
|
-
try:
|
5529
|
-
secret = client.get_secret(
|
5530
|
-
name_id_or_prefix=connector.secret_id,
|
5531
|
-
allow_partial_id_match=False,
|
5532
|
-
allow_partial_name_match=False,
|
5533
|
-
)
|
5534
|
-
except KeyError as err:
|
5535
|
-
logger.error(
|
5536
|
-
"Unable to retrieve secret values associated with "
|
5537
|
-
f"service connector '{connector.name}': {err}"
|
5538
|
-
)
|
5539
|
-
else:
|
5540
|
-
# Add secret values to connector configuration
|
5541
|
-
connector.secrets.update(secret.values)
|
5542
|
-
|
5543
5528
|
return connector
|
5544
5529
|
|
5545
5530
|
def list_service_connectors(
|
@@ -5558,8 +5543,8 @@ class Client(metaclass=ClientMetaClass):
|
|
5558
5543
|
resource_id: Optional[str] = None,
|
5559
5544
|
user: Optional[Union[UUID, str]] = None,
|
5560
5545
|
labels: Optional[Dict[str, Optional[str]]] = None,
|
5561
|
-
secret_id: Optional[Union[str, UUID]] = None,
|
5562
5546
|
hydrate: bool = False,
|
5547
|
+
expand_secrets: bool = False,
|
5563
5548
|
) -> Page[ServiceConnectorResponse]:
|
5564
5549
|
"""Lists all registered service connectors.
|
5565
5550
|
|
@@ -5580,10 +5565,10 @@ class Client(metaclass=ClientMetaClass):
|
|
5580
5565
|
user: Filter by user name/ID.
|
5581
5566
|
name: The name of the service connector to filter by.
|
5582
5567
|
labels: The labels of the service connector to filter by.
|
5583
|
-
secret_id: Filter by the id of the secret that is referenced by the
|
5584
|
-
service connector.
|
5585
5568
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
5586
5569
|
by including metadata fields in the response.
|
5570
|
+
expand_secrets: If True, expand the secrets for the service
|
5571
|
+
connectors.
|
5587
5572
|
|
5588
5573
|
Returns:
|
5589
5574
|
A page of service connectors.
|
@@ -5603,11 +5588,11 @@ class Client(metaclass=ClientMetaClass):
|
|
5603
5588
|
created=created,
|
5604
5589
|
updated=updated,
|
5605
5590
|
labels=labels,
|
5606
|
-
secret_id=secret_id,
|
5607
5591
|
)
|
5608
5592
|
return self.zen_store.list_service_connectors(
|
5609
5593
|
filter_model=connector_filter_model,
|
5610
5594
|
hydrate=hydrate,
|
5595
|
+
expand_secrets=expand_secrets,
|
5611
5596
|
)
|
5612
5597
|
|
5613
5598
|
def update_service_connector(
|
@@ -5691,7 +5676,9 @@ class Client(metaclass=ClientMetaClass):
|
|
5691
5676
|
connector_model = self.get_service_connector(
|
5692
5677
|
name_id_or_prefix,
|
5693
5678
|
allow_name_prefix_match=False,
|
5694
|
-
|
5679
|
+
# We need the existing secrets only if a new configuration is not
|
5680
|
+
# provided.
|
5681
|
+
expand_secrets=configuration is None,
|
5695
5682
|
)
|
5696
5683
|
|
5697
5684
|
connector_instance: Optional[ServiceConnector] = None
|
@@ -5736,23 +5723,16 @@ class Client(metaclass=ClientMetaClass):
|
|
5736
5723
|
)
|
5737
5724
|
|
5738
5725
|
# Validate and configure the resources
|
5739
|
-
|
5726
|
+
connector_update.validate_and_configure_resources(
|
5727
|
+
connector_type=connector,
|
5728
|
+
resource_types=resource_types,
|
5729
|
+
resource_id=resource_id,
|
5740
5730
|
# The supplied configuration is a drop-in replacement for the
|
5741
|
-
# existing configuration
|
5742
|
-
|
5743
|
-
|
5744
|
-
|
5745
|
-
|
5746
|
-
configuration=configuration,
|
5747
|
-
)
|
5748
|
-
else:
|
5749
|
-
connector_update.validate_and_configure_resources(
|
5750
|
-
connector_type=connector,
|
5751
|
-
resource_types=resource_types,
|
5752
|
-
resource_id=resource_id,
|
5753
|
-
configuration=connector_model.configuration,
|
5754
|
-
secrets=connector_model.secrets,
|
5755
|
-
)
|
5731
|
+
# existing configuration
|
5732
|
+
configuration=configuration
|
5733
|
+
if configuration is not None
|
5734
|
+
else connector_model.configuration,
|
5735
|
+
)
|
5756
5736
|
|
5757
5737
|
# Add the labels
|
5758
5738
|
if labels is not None:
|
@@ -5912,6 +5892,12 @@ class Client(metaclass=ClientMetaClass):
|
|
5912
5892
|
list_resources=list_resources,
|
5913
5893
|
)
|
5914
5894
|
else:
|
5895
|
+
# Get the service connector model, with full secrets
|
5896
|
+
service_connector = self.get_service_connector(
|
5897
|
+
name_id_or_prefix=name_id_or_prefix,
|
5898
|
+
allow_name_prefix_match=False,
|
5899
|
+
expand_secrets=True,
|
5900
|
+
)
|
5915
5901
|
connector_instance = (
|
5916
5902
|
service_connector_registry.instantiate_connector(
|
5917
5903
|
model=service_connector
|
@@ -6034,6 +6020,12 @@ class Client(metaclass=ClientMetaClass):
|
|
6034
6020
|
# server-side implementation may not be able to do so
|
6035
6021
|
connector_client.verify()
|
6036
6022
|
else:
|
6023
|
+
# Get the service connector model, with full secrets
|
6024
|
+
service_connector = self.get_service_connector(
|
6025
|
+
name_id_or_prefix=name_id_or_prefix,
|
6026
|
+
allow_name_prefix_match=False,
|
6027
|
+
expand_secrets=True,
|
6028
|
+
)
|
6037
6029
|
connector_instance = (
|
6038
6030
|
service_connector_registry.instantiate_connector(
|
6039
6031
|
model=service_connector
|
zenml/config/__init__.py
CHANGED
@@ -23,12 +23,23 @@ configuration. This ``GlobalConfiguration`` object handles the serialization and
|
|
23
23
|
deserialization of the configuration options that are stored in the file in
|
24
24
|
order to persist the configuration across sessions.
|
25
25
|
"""
|
26
|
-
from zenml.config.docker_settings import
|
27
|
-
|
26
|
+
from zenml.config.docker_settings import (
|
27
|
+
DockerSettings,
|
28
|
+
PythonPackageInstaller,
|
29
|
+
PythonEnvironmentExportMethod,
|
30
|
+
)
|
31
|
+
from zenml.config.resource_settings import ResourceSettings, ByteUnit
|
28
32
|
from zenml.config.retry_config import StepRetryConfig
|
33
|
+
from zenml.config.schedule import Schedule
|
34
|
+
from zenml.config.store_config import StoreConfiguration
|
29
35
|
|
30
36
|
__all__ = [
|
31
37
|
"DockerSettings",
|
38
|
+
"PythonPackageInstaller",
|
39
|
+
"PythonEnvironmentExportMethod",
|
32
40
|
"ResourceSettings",
|
41
|
+
"ByteUnit",
|
33
42
|
"StepRetryConfig",
|
43
|
+
"Schedule",
|
44
|
+
"StoreConfiguration",
|
34
45
|
]
|
zenml/constants.py
CHANGED
@@ -173,7 +173,6 @@ ENV_ZENML_DISABLE_STEP_LOGS_STORAGE = "ZENML_DISABLE_STEP_LOGS_STORAGE"
|
|
173
173
|
ENV_ZENML_DISABLE_STEP_NAMES_IN_LOGS = "ZENML_DISABLE_STEP_NAMES_IN_LOGS"
|
174
174
|
ENV_ZENML_IGNORE_FAILURE_HOOK = "ZENML_IGNORE_FAILURE_HOOK"
|
175
175
|
ENV_ZENML_CUSTOM_SOURCE_ROOT = "ZENML_CUSTOM_SOURCE_ROOT"
|
176
|
-
ENV_ZENML_WHEEL_PACKAGE_NAME = "ZENML_WHEEL_PACKAGE_NAME"
|
177
176
|
ENV_ZENML_PIPELINE_RUN_API_TOKEN_EXPIRATION = (
|
178
177
|
"ZENML_PIPELINE_API_TOKEN_EXPIRATION"
|
179
178
|
)
|
zenml/exceptions.py
CHANGED
@@ -220,3 +220,19 @@ class CustomFlavorImportError(ImportError):
|
|
220
220
|
|
221
221
|
class MaxConcurrentTasksError(ZenMLBaseException):
|
222
222
|
"""Raised when the maximum number of concurrent tasks is reached."""
|
223
|
+
|
224
|
+
|
225
|
+
class RunMonitoringError(ZenMLBaseException):
|
226
|
+
"""Raised when an error occurs while monitoring a pipeline run."""
|
227
|
+
|
228
|
+
def __init__(
|
229
|
+
self,
|
230
|
+
original_exception: BaseException,
|
231
|
+
) -> None:
|
232
|
+
"""Initializes the error.
|
233
|
+
|
234
|
+
Args:
|
235
|
+
original_exception: The original exception that occurred while
|
236
|
+
monitoring the pipeline run.
|
237
|
+
"""
|
238
|
+
self.original_exception = original_exception
|
@@ -38,7 +38,7 @@ from zenml.integrations.airflow.flavors.airflow_orchestrator_flavor import (
|
|
38
38
|
)
|
39
39
|
from zenml.io import fileio
|
40
40
|
from zenml.logger import get_logger
|
41
|
-
from zenml.orchestrators import ContainerizedOrchestrator
|
41
|
+
from zenml.orchestrators import ContainerizedOrchestrator, SubmissionResult
|
42
42
|
from zenml.orchestrators.utils import get_orchestrator_run_name
|
43
43
|
from zenml.stack import StackValidator
|
44
44
|
from zenml.utils import io_utils
|
@@ -191,21 +191,29 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
191
191
|
if self.config.local:
|
192
192
|
stack.check_local_paths()
|
193
193
|
|
194
|
-
def
|
194
|
+
def submit_pipeline(
|
195
195
|
self,
|
196
196
|
deployment: "PipelineDeploymentResponse",
|
197
197
|
stack: "Stack",
|
198
198
|
environment: Dict[str, str],
|
199
199
|
placeholder_run: Optional["PipelineRunResponse"] = None,
|
200
|
-
) ->
|
201
|
-
"""
|
200
|
+
) -> Optional[SubmissionResult]:
|
201
|
+
"""Submits a pipeline to the orchestrator.
|
202
|
+
|
203
|
+
This method should only submit the pipeline and not wait for it to
|
204
|
+
complete. If the orchestrator is configured to wait for the pipeline run
|
205
|
+
to complete, a function that waits for the pipeline run to complete can
|
206
|
+
be passed as part of the submission result.
|
202
207
|
|
203
208
|
Args:
|
204
|
-
deployment: The pipeline deployment to
|
209
|
+
deployment: The pipeline deployment to submit.
|
205
210
|
stack: The stack the pipeline will run on.
|
206
211
|
environment: Environment variables to set in the orchestration
|
207
|
-
environment.
|
212
|
+
environment. These don't need to be set if running locally.
|
208
213
|
placeholder_run: An optional placeholder run for the deployment.
|
214
|
+
|
215
|
+
Returns:
|
216
|
+
Optional submission result.
|
209
217
|
"""
|
210
218
|
pipeline_settings = cast(
|
211
219
|
AirflowOrchestratorSettings, self.get_settings(deployment)
|
@@ -277,6 +285,7 @@ class AirflowOrchestrator(ContainerizedOrchestrator):
|
|
277
285
|
dag_generator_values=dag_generator_values,
|
278
286
|
output_dir=pipeline_settings.dag_output_dir or self.dags_directory,
|
279
287
|
)
|
288
|
+
return None
|
280
289
|
|
281
290
|
def _apply_resource_settings(
|
282
291
|
self,
|
@@ -81,7 +81,9 @@ class AWSContainerRegistry(BaseContainerRegistry):
|
|
81
81
|
"""
|
82
82
|
if self.connector:
|
83
83
|
try:
|
84
|
-
model = Client().get_service_connector(
|
84
|
+
model = Client().get_service_connector(
|
85
|
+
self.connector, expand_secrets=True
|
86
|
+
)
|
85
87
|
connector = service_connector_registry.instantiate_connector(
|
86
88
|
model=model
|
87
89
|
)
|