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.
Files changed (54) hide show
  1. zenml/VERSION +1 -1
  2. zenml/cli/base.py +3 -2
  3. zenml/cli/login.py +21 -3
  4. zenml/cli/service_connectors.py +5 -12
  5. zenml/cli/stack.py +1 -5
  6. zenml/cli/utils.py +8 -52
  7. zenml/client.py +32 -40
  8. zenml/config/__init__.py +13 -2
  9. zenml/constants.py +0 -1
  10. zenml/exceptions.py +16 -0
  11. zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +15 -6
  12. zenml/integrations/aws/container_registries/aws_container_registry.py +3 -1
  13. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +54 -58
  14. zenml/integrations/azure/orchestrators/azureml_orchestrator.py +28 -19
  15. zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +19 -63
  16. zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +8 -3
  17. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +36 -61
  18. zenml/integrations/hyperai/orchestrators/hyperai_orchestrator.py +19 -22
  19. zenml/integrations/integration.py +23 -58
  20. zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +28 -31
  21. zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +33 -20
  22. zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +25 -100
  23. zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +19 -8
  24. zenml/integrations/skypilot/utils.py +17 -13
  25. zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +28 -12
  26. zenml/models/__init__.py +2 -0
  27. zenml/models/v2/core/service_connector.py +178 -108
  28. zenml/models/v2/core/step_run.py +1 -0
  29. zenml/orchestrators/__init__.py +2 -0
  30. zenml/orchestrators/base_orchestrator.py +137 -66
  31. zenml/orchestrators/input_utils.py +5 -13
  32. zenml/orchestrators/local/local_orchestrator.py +19 -9
  33. zenml/orchestrators/local_docker/local_docker_orchestrator.py +15 -5
  34. zenml/orchestrators/publish_utils.py +24 -0
  35. zenml/orchestrators/step_run_utils.py +1 -2
  36. zenml/pipelines/run_utils.py +12 -7
  37. zenml/service_connectors/service_connector.py +11 -61
  38. zenml/service_connectors/service_connector_utils.py +4 -2
  39. zenml/step_operators/step_operator_entrypoint_configuration.py +1 -1
  40. zenml/utils/package_utils.py +111 -1
  41. zenml/zen_server/routers/service_connectors_endpoints.py +7 -22
  42. zenml/zen_stores/migrations/versions/5bb25e95849c_add_internal_secrets.py +62 -0
  43. zenml/zen_stores/rest_zen_store.py +204 -132
  44. zenml/zen_stores/schemas/secret_schemas.py +5 -0
  45. zenml/zen_stores/schemas/service_connector_schemas.py +16 -14
  46. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +4 -1
  47. zenml/zen_stores/sql_zen_store.py +241 -119
  48. zenml/zen_stores/zen_store_interface.py +9 -1
  49. {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/METADATA +1 -1
  50. {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/RECORD +53 -53
  51. zenml/utils/integration_utils.py +0 -34
  52. {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/LICENSE +0 -0
  53. {zenml_nightly-0.83.1.dev20250624.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/WHEEL +0 -0
  54. {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.dev20250624
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"] = cli_utils.get_package_information()
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"] = cli_utils.get_package_information(
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(server_url, api_key=api_key, pro_server=True)
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(server.url, api_key=api_key, pro_server=True)
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
 
@@ -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
- load_secrets=True,
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
- load_secrets=True,
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.full_configuration
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.full_configuration
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.get(
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 is_installed_in_python_environment("uv"):
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 is_installed_in_python_environment("uv"):
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 is_installed_in_python_environment("pip")
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 and len(connector.secrets) == 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.copy()
1846
- secrets = connector.secrets.copy()
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
- try:
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
- load_secrets=True,
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
- if configuration is not None:
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 and secrets
5742
- connector_update.validate_and_configure_resources(
5743
- connector_type=connector,
5744
- resource_types=resource_types,
5745
- resource_id=resource_id,
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 DockerSettings
27
- from zenml.config.resource_settings import ResourceSettings
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 prepare_or_run_pipeline(
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
- ) -> Any:
201
- """Creates and writes an Airflow DAG zip file.
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 prepare or run.
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(self.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
  )