zenml-nightly 0.68.0.dev20241027__py3-none-any.whl → 0.68.1.dev20241101__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 +17 -11
- RELEASE_NOTES.md +9 -0
- zenml/VERSION +1 -1
- zenml/__init__.py +1 -1
- zenml/analytics/context.py +16 -1
- zenml/analytics/utils.py +18 -7
- zenml/artifacts/utils.py +40 -216
- zenml/cli/__init__.py +63 -90
- zenml/cli/base.py +3 -3
- zenml/cli/login.py +951 -0
- zenml/cli/server.py +462 -353
- zenml/cli/service_accounts.py +4 -4
- zenml/cli/stack.py +77 -2
- zenml/cli/stack_components.py +5 -16
- zenml/cli/user_management.py +0 -12
- zenml/cli/utils.py +24 -77
- zenml/client.py +46 -14
- zenml/config/compiler.py +1 -0
- zenml/config/global_config.py +9 -0
- zenml/config/pipeline_configurations.py +2 -1
- zenml/config/pipeline_run_configuration.py +2 -1
- zenml/constants.py +3 -9
- zenml/enums.py +1 -1
- zenml/exceptions.py +11 -0
- zenml/integrations/github/code_repositories/github_code_repository.py +1 -1
- zenml/login/__init__.py +16 -0
- zenml/login/credentials.py +346 -0
- zenml/login/credentials_store.py +603 -0
- zenml/login/pro/__init__.py +16 -0
- zenml/login/pro/client.py +496 -0
- zenml/login/pro/constants.py +34 -0
- zenml/login/pro/models.py +25 -0
- zenml/login/pro/organization/__init__.py +14 -0
- zenml/login/pro/organization/client.py +79 -0
- zenml/login/pro/organization/models.py +32 -0
- zenml/login/pro/tenant/__init__.py +14 -0
- zenml/login/pro/tenant/client.py +92 -0
- zenml/login/pro/tenant/models.py +174 -0
- zenml/login/pro/utils.py +121 -0
- zenml/{cli → login}/web_login.py +64 -28
- zenml/materializers/base_materializer.py +43 -9
- zenml/materializers/built_in_materializer.py +1 -1
- zenml/metadata/metadata_types.py +49 -0
- zenml/model/model.py +0 -38
- zenml/models/__init__.py +3 -0
- zenml/models/v2/base/base.py +12 -8
- zenml/models/v2/base/filter.py +9 -0
- zenml/models/v2/core/artifact_version.py +49 -10
- zenml/models/v2/core/component.py +54 -19
- zenml/models/v2/core/flavor.py +13 -13
- zenml/models/v2/core/model.py +3 -1
- zenml/models/v2/core/model_version.py +3 -5
- zenml/models/v2/core/model_version_artifact.py +3 -1
- zenml/models/v2/core/model_version_pipeline_run.py +3 -1
- zenml/models/v2/core/pipeline.py +3 -1
- zenml/models/v2/core/pipeline_run.py +23 -1
- zenml/models/v2/core/run_template.py +3 -1
- zenml/models/v2/core/stack.py +7 -3
- zenml/models/v2/core/step_run.py +43 -2
- zenml/models/v2/misc/auth_models.py +11 -2
- zenml/models/v2/misc/server_models.py +2 -0
- zenml/orchestrators/base_orchestrator.py +8 -4
- zenml/orchestrators/step_launcher.py +1 -0
- zenml/orchestrators/step_run_utils.py +10 -2
- zenml/orchestrators/step_runner.py +67 -55
- zenml/orchestrators/utils.py +45 -22
- zenml/pipelines/pipeline_decorator.py +5 -0
- zenml/pipelines/pipeline_definition.py +206 -160
- zenml/pipelines/run_utils.py +11 -10
- zenml/services/local/local_daemon_entrypoint.py +4 -4
- zenml/services/service.py +2 -2
- zenml/stack/stack.py +2 -6
- zenml/stack/stack_component.py +2 -7
- zenml/stack/utils.py +26 -14
- zenml/steps/base_step.py +8 -2
- zenml/steps/step_context.py +0 -3
- zenml/steps/step_invocation.py +14 -5
- zenml/steps/utils.py +1 -0
- zenml/utils/materializer_utils.py +1 -1
- zenml/utils/requirements_utils.py +71 -0
- zenml/utils/singleton.py +15 -3
- zenml/utils/source_utils.py +39 -2
- zenml/utils/visualization_utils.py +1 -1
- zenml/zen_server/auth.py +44 -39
- zenml/zen_server/deploy/__init__.py +7 -7
- zenml/zen_server/deploy/base_provider.py +46 -73
- zenml/zen_server/deploy/{local → daemon}/__init__.py +3 -3
- zenml/zen_server/deploy/{local/local_provider.py → daemon/daemon_provider.py} +44 -63
- zenml/zen_server/deploy/{local/local_zen_server.py → daemon/daemon_zen_server.py} +50 -22
- zenml/zen_server/deploy/deployer.py +90 -171
- zenml/zen_server/deploy/deployment.py +20 -12
- zenml/zen_server/deploy/docker/docker_provider.py +9 -28
- zenml/zen_server/deploy/docker/docker_zen_server.py +19 -3
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +2 -2
- zenml/zen_server/exceptions.py +11 -0
- zenml/zen_server/jwt.py +9 -9
- zenml/zen_server/routers/auth_endpoints.py +30 -8
- zenml/zen_server/routers/stack_components_endpoints.py +1 -1
- zenml/zen_server/routers/workspaces_endpoints.py +1 -1
- zenml/zen_server/template_execution/runner_entrypoint_configuration.py +7 -4
- zenml/zen_server/template_execution/utils.py +6 -61
- zenml/zen_server/utils.py +64 -36
- zenml/zen_stores/base_zen_store.py +4 -49
- zenml/zen_stores/migrations/versions/0.68.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/c22561cbb3a9_add_artifact_unique_constraints.py +86 -0
- zenml/zen_stores/rest_zen_store.py +325 -147
- zenml/zen_stores/schemas/api_key_schemas.py +9 -4
- zenml/zen_stores/schemas/artifact_schemas.py +21 -2
- zenml/zen_stores/schemas/artifact_visualization_schemas.py +1 -1
- zenml/zen_stores/schemas/component_schemas.py +49 -6
- zenml/zen_stores/schemas/device_schemas.py +9 -4
- zenml/zen_stores/schemas/flavor_schemas.py +1 -1
- zenml/zen_stores/schemas/model_schemas.py +1 -1
- zenml/zen_stores/schemas/service_schemas.py +1 -1
- zenml/zen_stores/schemas/step_run_schemas.py +1 -1
- zenml/zen_stores/schemas/trigger_schemas.py +1 -1
- zenml/zen_stores/sql_zen_store.py +393 -140
- zenml/zen_stores/template_utils.py +3 -1
- {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/METADATA +18 -12
- {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/RECORD +124 -107
- zenml/api.py +0 -60
- {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/entry_points.txt +0 -0
zenml/zen_server/utils.py
CHANGED
@@ -39,13 +39,14 @@ from zenml.constants import (
|
|
39
39
|
INFO,
|
40
40
|
VERSION_1,
|
41
41
|
)
|
42
|
+
from zenml.enums import StoreType
|
42
43
|
from zenml.exceptions import IllegalOperationError, OAuthError
|
43
44
|
from zenml.logger import get_logger
|
44
45
|
from zenml.plugins.plugin_flavor_registry import PluginFlavorRegistry
|
45
|
-
from zenml.zen_server.deploy.deployment import
|
46
|
-
|
47
|
-
LocalServerDeploymentConfig,
|
46
|
+
from zenml.zen_server.deploy.deployment import (
|
47
|
+
LocalServerDeployment,
|
48
48
|
)
|
49
|
+
from zenml.zen_server.deploy.exceptions import ServerDeploymentNotFoundError
|
49
50
|
from zenml.zen_server.exceptions import http_exception_from_error
|
50
51
|
from zenml.zen_server.feature_gate.feature_gate_interface import (
|
51
52
|
FeatureGateInterface,
|
@@ -236,7 +237,7 @@ def server_config() -> ServerConfiguration:
|
|
236
237
|
return _server_config
|
237
238
|
|
238
239
|
|
239
|
-
def get_local_server() -> Optional["
|
240
|
+
def get_local_server() -> Optional["LocalServerDeployment"]:
|
240
241
|
"""Get the active local server.
|
241
242
|
|
242
243
|
Call this function to retrieve the local server deployed on this machine.
|
@@ -245,48 +246,75 @@ def get_local_server() -> Optional["ServerDeployment"]:
|
|
245
246
|
The local server deployment or None, if no local server deployment was
|
246
247
|
found.
|
247
248
|
"""
|
248
|
-
from zenml.zen_server.deploy.deployer import
|
249
|
+
from zenml.zen_server.deploy.deployer import LocalServerDeployer
|
249
250
|
|
250
|
-
deployer =
|
251
|
-
|
252
|
-
|
251
|
+
deployer = LocalServerDeployer()
|
252
|
+
try:
|
253
|
+
return deployer.get_server()
|
254
|
+
except ServerDeploymentNotFoundError:
|
253
255
|
return None
|
254
256
|
|
255
|
-
return servers[0]
|
256
257
|
|
258
|
+
def connected_to_local_server() -> bool:
|
259
|
+
"""Check if the client is connected to a local server.
|
257
260
|
|
258
|
-
|
259
|
-
|
261
|
+
Returns:
|
262
|
+
True if the client is connected to a local server, False otherwise.
|
263
|
+
"""
|
264
|
+
from zenml.zen_server.deploy.deployer import LocalServerDeployer
|
260
265
|
|
261
|
-
|
262
|
-
|
263
|
-
- If the client is connected to a server, that server has precedence.
|
264
|
-
- If no server is connected, the local server is used, if present.
|
266
|
+
deployer = LocalServerDeployer()
|
267
|
+
return deployer.is_connected_to_server()
|
265
268
|
|
266
|
-
|
267
|
-
|
269
|
+
|
270
|
+
def show_dashboard(
|
271
|
+
local: bool = False,
|
272
|
+
ngrok_token: Optional[str] = None,
|
273
|
+
) -> None:
|
274
|
+
"""Show the ZenML dashboard.
|
275
|
+
|
276
|
+
Args:
|
277
|
+
local: Whether to show the dashboard for the local server or the
|
278
|
+
one for the active server.
|
279
|
+
ngrok_token: An ngrok auth token to use for exposing the ZenML
|
280
|
+
dashboard on a public domain. Primarily used for accessing the
|
281
|
+
dashboard in Colab.
|
268
282
|
|
269
283
|
Raises:
|
270
|
-
RuntimeError: If no server is
|
284
|
+
RuntimeError: If no server is connected.
|
271
285
|
"""
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
286
|
+
from zenml.utils.dashboard_utils import show_dashboard
|
287
|
+
from zenml.utils.networking_utils import get_or_create_ngrok_tunnel
|
288
|
+
|
289
|
+
url: Optional[str] = None
|
290
|
+
if not local:
|
291
|
+
gc = GlobalConfiguration()
|
292
|
+
if gc.store_configuration.type == StoreType.REST:
|
293
|
+
url = gc.store_configuration.url
|
294
|
+
|
295
|
+
if not url:
|
296
|
+
# Else, check for local servers
|
297
|
+
server = get_local_server()
|
298
|
+
if server and server.status and server.status.url:
|
299
|
+
url = server.status.url
|
300
|
+
|
301
|
+
if not url:
|
302
|
+
raise RuntimeError(
|
303
|
+
"ZenML is not connected to any server right now. Please use "
|
304
|
+
"`zenml login` to connect to a server or spin up a new local server "
|
305
|
+
"via `zenml login --local`."
|
306
|
+
)
|
307
|
+
|
308
|
+
if ngrok_token:
|
309
|
+
parsed_url = urlparse(url)
|
310
|
+
|
311
|
+
ngrok_url = get_or_create_ngrok_tunnel(
|
312
|
+
ngrok_token=ngrok_token, port=parsed_url.port or 80
|
313
|
+
)
|
314
|
+
logger.debug(f"Tunneling dashboard from {url} to {ngrok_url}.")
|
315
|
+
url = ngrok_url
|
316
|
+
|
317
|
+
show_dashboard(url)
|
290
318
|
|
291
319
|
|
292
320
|
F = TypeVar("F", bound=Callable[..., Any])
|
@@ -24,11 +24,9 @@ from typing import (
|
|
24
24
|
Type,
|
25
25
|
Union,
|
26
26
|
)
|
27
|
-
from urllib.parse import urlparse
|
28
27
|
from uuid import UUID
|
29
28
|
|
30
29
|
from pydantic import BaseModel, ConfigDict, model_validator
|
31
|
-
from requests import ConnectionError
|
32
30
|
|
33
31
|
import zenml
|
34
32
|
from zenml.config.global_config import GlobalConfiguration
|
@@ -39,13 +37,11 @@ from zenml.constants import (
|
|
39
37
|
DEFAULT_WORKSPACE_NAME,
|
40
38
|
ENV_ZENML_DEFAULT_WORKSPACE_NAME,
|
41
39
|
IS_DEBUG_ENV,
|
42
|
-
ZENML_PRO_CONNECTION_ISSUES_SUSPENDED_PAUSED_TENANT_HINT,
|
43
40
|
)
|
44
41
|
from zenml.enums import (
|
45
42
|
SecretsStoreType,
|
46
43
|
StoreType,
|
47
44
|
)
|
48
|
-
from zenml.exceptions import AuthorizationException
|
49
45
|
from zenml.logger import get_logger
|
50
46
|
from zenml.models import (
|
51
47
|
ServerDatabaseType,
|
@@ -57,9 +53,6 @@ from zenml.models import (
|
|
57
53
|
WorkspaceResponse,
|
58
54
|
)
|
59
55
|
from zenml.utils.pydantic_utils import before_validator_handler
|
60
|
-
from zenml.zen_stores.secrets_stores.sql_secrets_store import (
|
61
|
-
SqlSecretsStoreConfiguration,
|
62
|
-
)
|
63
56
|
from zenml.zen_stores.zen_store_interface import ZenStoreInterface
|
64
57
|
|
65
58
|
logger = get_logger(__name__)
|
@@ -136,51 +129,10 @@ class BaseZenStore(
|
|
136
129
|
stack and user in the store will be skipped.
|
137
130
|
**kwargs: Additional keyword arguments to pass to the Pydantic
|
138
131
|
constructor.
|
139
|
-
|
140
|
-
Raises:
|
141
|
-
RuntimeError: If the store cannot be initialized.
|
142
|
-
AuthorizationException: If the store cannot be initialized due to
|
143
|
-
authentication errors.
|
144
132
|
"""
|
145
133
|
super().__init__(**kwargs)
|
146
134
|
|
147
|
-
|
148
|
-
self._initialize()
|
149
|
-
|
150
|
-
# Handle cases where the ZenML server is not available
|
151
|
-
except ConnectionError as e:
|
152
|
-
error_message = (
|
153
|
-
"Cannot connect to the ZenML database because the ZenML server "
|
154
|
-
f"at {self.url} is not running."
|
155
|
-
)
|
156
|
-
if urlparse(self.url).hostname in ["localhost", "127.0.0.1"]:
|
157
|
-
recommendation = (
|
158
|
-
"Please run `zenml down` and `zenml up` to restart the "
|
159
|
-
"server."
|
160
|
-
)
|
161
|
-
else:
|
162
|
-
recommendation = (
|
163
|
-
"Please run `zenml disconnect` and `zenml connect --url "
|
164
|
-
f"{self.url}` to reconnect to the server."
|
165
|
-
)
|
166
|
-
raise RuntimeError(f"{error_message}\n{recommendation}") from e
|
167
|
-
|
168
|
-
except AuthorizationException as e:
|
169
|
-
raise AuthorizationException(
|
170
|
-
f"Authorization failed for store at '{self.url}'. Please check "
|
171
|
-
f"your credentials: {str(e)}"
|
172
|
-
)
|
173
|
-
|
174
|
-
except Exception as e:
|
175
|
-
zenml_pro_extra = ""
|
176
|
-
if ".zenml.io" in self.url:
|
177
|
-
zenml_pro_extra = (
|
178
|
-
ZENML_PRO_CONNECTION_ISSUES_SUSPENDED_PAUSED_TENANT_HINT
|
179
|
-
)
|
180
|
-
raise RuntimeError(
|
181
|
-
f"Error initializing {self.type.value} store with URL "
|
182
|
-
f"'{self.url}': {str(e)}" + zenml_pro_extra
|
183
|
-
) from e
|
135
|
+
self._initialize()
|
184
136
|
|
185
137
|
if not skip_default_registrations:
|
186
138
|
logger.debug("Initializing database")
|
@@ -293,6 +245,9 @@ class BaseZenStore(
|
|
293
245
|
Returns:
|
294
246
|
The default store configuration.
|
295
247
|
"""
|
248
|
+
from zenml.zen_stores.secrets_stores.sql_secrets_store import (
|
249
|
+
SqlSecretsStoreConfiguration,
|
250
|
+
)
|
296
251
|
from zenml.zen_stores.sql_zen_store import SqlZenStoreConfiguration
|
297
252
|
|
298
253
|
config = SqlZenStoreConfiguration(
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""Release [0.68.1].
|
2
|
+
|
3
|
+
Revision ID: 0.68.1
|
4
|
+
Revises: 0.68.0
|
5
|
+
Create Date: 2024-10-28 10:34:17.307663
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
# revision identifiers, used by Alembic.
|
10
|
+
revision = "0.68.1"
|
11
|
+
down_revision = "0.68.0"
|
12
|
+
branch_labels = None
|
13
|
+
depends_on = None
|
14
|
+
|
15
|
+
|
16
|
+
def upgrade() -> None:
|
17
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
18
|
+
pass
|
19
|
+
|
20
|
+
|
21
|
+
def downgrade() -> None:
|
22
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
23
|
+
pass
|
@@ -0,0 +1,86 @@
|
|
1
|
+
"""Add artifact unique constraints [c22561cbb3a9].
|
2
|
+
|
3
|
+
Revision ID: c22561cbb3a9
|
4
|
+
Revises: 0.68.1
|
5
|
+
Create Date: 2024-10-17 16:41:25.053677
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
from collections import defaultdict
|
10
|
+
from typing import Dict, Set
|
11
|
+
|
12
|
+
import sqlalchemy as sa
|
13
|
+
from alembic import op
|
14
|
+
|
15
|
+
# revision identifiers, used by Alembic.
|
16
|
+
revision = "c22561cbb3a9"
|
17
|
+
down_revision = "0.68.1"
|
18
|
+
branch_labels = None
|
19
|
+
depends_on = None
|
20
|
+
|
21
|
+
|
22
|
+
def resolve_duplicate_versions() -> None:
|
23
|
+
"""Resolve duplicate artifact versions."""
|
24
|
+
connection = op.get_bind()
|
25
|
+
|
26
|
+
meta = sa.MetaData()
|
27
|
+
meta.reflect(
|
28
|
+
bind=op.get_bind(),
|
29
|
+
only=("artifact_version",),
|
30
|
+
)
|
31
|
+
|
32
|
+
artifact_version_table = sa.Table("artifact_version", meta)
|
33
|
+
query = sa.select(
|
34
|
+
artifact_version_table.c.id,
|
35
|
+
artifact_version_table.c.artifact_id,
|
36
|
+
artifact_version_table.c.version,
|
37
|
+
)
|
38
|
+
|
39
|
+
versions_per_artifact: Dict[str, Set[str]] = defaultdict(set)
|
40
|
+
|
41
|
+
for id, artifact_id, version in connection.execute(query).fetchall():
|
42
|
+
versions = versions_per_artifact[artifact_id]
|
43
|
+
if version in versions:
|
44
|
+
for suffix_length in range(4, len(id)):
|
45
|
+
new_version = f"{version}-{id[:suffix_length]}"
|
46
|
+
if new_version not in versions:
|
47
|
+
version = new_version
|
48
|
+
break
|
49
|
+
|
50
|
+
connection.execute(
|
51
|
+
sa.update(artifact_version_table)
|
52
|
+
.where(artifact_version_table.c.id == id)
|
53
|
+
.values(version=version)
|
54
|
+
)
|
55
|
+
|
56
|
+
versions.add(version)
|
57
|
+
|
58
|
+
|
59
|
+
def upgrade() -> None:
|
60
|
+
"""Upgrade database schema and/or data, creating a new revision."""
|
61
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
62
|
+
resolve_duplicate_versions()
|
63
|
+
|
64
|
+
with op.batch_alter_table("artifact", schema=None) as batch_op:
|
65
|
+
batch_op.create_unique_constraint("unique_artifact_name", ["name"])
|
66
|
+
|
67
|
+
with op.batch_alter_table("artifact_version", schema=None) as batch_op:
|
68
|
+
batch_op.create_unique_constraint(
|
69
|
+
"unique_version_for_artifact_id", ["version", "artifact_id"]
|
70
|
+
)
|
71
|
+
|
72
|
+
# ### end Alembic commands ###
|
73
|
+
|
74
|
+
|
75
|
+
def downgrade() -> None:
|
76
|
+
"""Downgrade database schema and/or data back to the previous revision."""
|
77
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
78
|
+
with op.batch_alter_table("artifact_version", schema=None) as batch_op:
|
79
|
+
batch_op.drop_constraint(
|
80
|
+
"unique_version_for_artifact_id", type_="unique"
|
81
|
+
)
|
82
|
+
|
83
|
+
with op.batch_alter_table("artifact", schema=None) as batch_op:
|
84
|
+
batch_op.drop_constraint("unique_artifact_name", type_="unique")
|
85
|
+
|
86
|
+
# ### end Alembic commands ###
|