zenml-nightly 0.83.1.dev20250625__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/service_connectors.py +5 -12
- zenml/cli/stack.py +1 -5
- zenml/cli/utils.py +8 -52
- zenml/client.py +32 -40
- zenml/integrations/aws/container_registries/aws_container_registry.py +3 -1
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +8 -3
- zenml/integrations/integration.py +23 -58
- zenml/models/__init__.py +2 -0
- zenml/models/v2/core/service_connector.py +178 -108
- zenml/service_connectors/service_connector.py +11 -61
- zenml/service_connectors/service_connector_utils.py +4 -2
- 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 +57 -4
- 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 +214 -102
- zenml/zen_stores/zen_store_interface.py +9 -1
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/METADATA +1 -1
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/RECORD +27 -27
- zenml/utils/integration_utils.py +0 -34
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.83.1.dev20250625.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/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
|
@@ -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
|
)
|
@@ -17,7 +17,10 @@ import os
|
|
17
17
|
import sys
|
18
18
|
from typing import Any, List, Set
|
19
19
|
|
20
|
-
|
20
|
+
if sys.version_info < (3, 10):
|
21
|
+
from importlib_metadata import distribution
|
22
|
+
else:
|
23
|
+
from importlib.metadata import distribution
|
21
24
|
|
22
25
|
from zenml.entrypoints.step_entrypoint_configuration import (
|
23
26
|
StepEntrypointConfiguration,
|
@@ -81,8 +84,10 @@ class DatabricksEntrypointConfiguration(StepEntrypointConfiguration):
|
|
81
84
|
"""Runs the step."""
|
82
85
|
# Get the wheel package and add it to the sys path
|
83
86
|
wheel_package = self.entrypoint_args[WHEEL_PACKAGE_OPTION]
|
84
|
-
|
85
|
-
|
87
|
+
|
88
|
+
dist = distribution(wheel_package)
|
89
|
+
project_root = os.path.join(dist.locate_file("."), wheel_package)
|
90
|
+
|
86
91
|
if project_root not in sys.path:
|
87
92
|
sys.path.insert(0, project_root)
|
88
93
|
sys.path.insert(-1, project_root)
|
@@ -13,16 +13,14 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Base and meta classes for ZenML integrations."""
|
15
15
|
|
16
|
-
import re
|
17
16
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, cast
|
18
17
|
|
19
|
-
import
|
20
|
-
from pkg_resources import Requirement
|
18
|
+
from packaging.requirements import Requirement
|
21
19
|
|
22
20
|
from zenml.integrations.registry import integration_registry
|
23
21
|
from zenml.logger import get_logger
|
24
22
|
from zenml.stack.flavor import Flavor
|
25
|
-
from zenml.utils.
|
23
|
+
from zenml.utils.package_utils import get_dependencies, requirement_installed
|
26
24
|
|
27
25
|
if TYPE_CHECKING:
|
28
26
|
from zenml.plugins.base_plugin_flavor import BasePluginFlavor
|
@@ -69,65 +67,32 @@ class Integration(metaclass=IntegrationMeta):
|
|
69
67
|
Returns:
|
70
68
|
True if all required packages are installed, False otherwise.
|
71
69
|
"""
|
72
|
-
for
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# Next, check if the dependencies (including extras) are
|
78
|
-
# installed
|
79
|
-
deps: List[Requirement] = []
|
80
|
-
|
81
|
-
_, extras = parse_requirement(r)
|
82
|
-
if extras:
|
83
|
-
extra_list = extras[1:-1].split(",")
|
84
|
-
for extra in extra_list:
|
85
|
-
try:
|
86
|
-
requirements = dist.requires(extras=[extra]) # type: ignore[arg-type]
|
87
|
-
except pkg_resources.UnknownExtra as e:
|
88
|
-
logger.debug(f"Unknown extra: {str(e)}")
|
89
|
-
return False
|
90
|
-
deps.extend(requirements)
|
91
|
-
else:
|
92
|
-
deps = dist.requires()
|
93
|
-
|
94
|
-
for ri in deps:
|
95
|
-
try:
|
96
|
-
# Remove the "extra == ..." part from the requirement string
|
97
|
-
cleaned_req = re.sub(
|
98
|
-
r"; extra == \"\w+\"", "", str(ri)
|
99
|
-
)
|
100
|
-
pkg_resources.get_distribution(cleaned_req)
|
101
|
-
except pkg_resources.DistributionNotFound as e:
|
102
|
-
logger.debug(
|
103
|
-
f"Unable to find required dependency "
|
104
|
-
f"'{e.req}' for requirement '{r}' "
|
105
|
-
f"necessary for integration '{cls.NAME}'."
|
106
|
-
)
|
107
|
-
return False
|
108
|
-
except pkg_resources.VersionConflict as e:
|
109
|
-
logger.debug(
|
110
|
-
f"Package version '{e.dist}' does not match "
|
111
|
-
f"version '{e.req}' required by '{r}' "
|
112
|
-
f"necessary for integration '{cls.NAME}'."
|
113
|
-
)
|
114
|
-
return False
|
115
|
-
|
116
|
-
except pkg_resources.DistributionNotFound as e:
|
117
|
-
logger.debug(
|
118
|
-
f"Unable to find required package '{e.req}' for "
|
119
|
-
f"integration {cls.NAME}."
|
120
|
-
)
|
121
|
-
return False
|
122
|
-
except pkg_resources.VersionConflict as e:
|
70
|
+
for requirement in cls.get_requirements():
|
71
|
+
parsed_requirement = Requirement(requirement)
|
72
|
+
|
73
|
+
if not requirement_installed(parsed_requirement):
|
123
74
|
logger.debug(
|
124
|
-
|
125
|
-
|
75
|
+
"Requirement '%s' for integration '%s' is not installed "
|
76
|
+
"or installed with the wrong version.",
|
77
|
+
requirement,
|
78
|
+
cls.NAME,
|
126
79
|
)
|
127
80
|
return False
|
128
81
|
|
82
|
+
dependencies = get_dependencies(parsed_requirement)
|
83
|
+
|
84
|
+
for dependency in dependencies:
|
85
|
+
if not requirement_installed(dependency):
|
86
|
+
logger.debug(
|
87
|
+
"Requirement '%s' for integration '%s' is not "
|
88
|
+
"installed or installed with the wrong version.",
|
89
|
+
dependency,
|
90
|
+
cls.NAME,
|
91
|
+
)
|
92
|
+
return False
|
93
|
+
|
129
94
|
logger.debug(
|
130
|
-
f"Integration {cls.NAME} is installed correctly with "
|
95
|
+
f"Integration '{cls.NAME}' is installed correctly with "
|
131
96
|
f"requirements {cls.get_requirements()}."
|
132
97
|
)
|
133
98
|
return True
|
zenml/models/__init__.py
CHANGED
@@ -286,6 +286,7 @@ from zenml.models.v2.core.service_account import (
|
|
286
286
|
ServiceAccountResponse,
|
287
287
|
)
|
288
288
|
from zenml.models.v2.core.service_connector import (
|
289
|
+
ServiceConnectorConfiguration,
|
289
290
|
ServiceConnectorRequest,
|
290
291
|
ServiceConnectorUpdate,
|
291
292
|
ServiceConnectorFilter,
|
@@ -739,6 +740,7 @@ __all__ = [
|
|
739
740
|
"ServiceAccountUpdate",
|
740
741
|
"ServiceAccountRequest",
|
741
742
|
"ServiceAccountResponse",
|
743
|
+
"ServiceConnectorConfiguration",
|
742
744
|
"ServiceConnectorRequest",
|
743
745
|
"ServiceConnectorUpdate",
|
744
746
|
"ServiceConnectorFilter",
|