zenml-nightly 0.70.0.dev20241122__py3-none-any.whl → 0.70.0.dev20241201__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/artifact_stores/base_artifact_store.py +2 -2
- zenml/artifacts/artifact_config.py +7 -1
- zenml/artifacts/utils.py +56 -31
- zenml/cli/__init__.py +18 -0
- zenml/cli/base.py +4 -4
- zenml/cli/login.py +26 -0
- zenml/cli/pipeline.py +80 -0
- zenml/cli/server.py +1 -1
- zenml/cli/service_connectors.py +3 -3
- zenml/cli/stack.py +0 -3
- zenml/cli/stack_components.py +0 -1
- zenml/cli/utils.py +0 -5
- zenml/client.py +8 -18
- zenml/config/compiler.py +12 -3
- zenml/config/pipeline_configurations.py +20 -0
- zenml/config/pipeline_run_configuration.py +1 -0
- zenml/config/step_configurations.py +21 -0
- zenml/constants.py +1 -0
- zenml/enums.py +1 -0
- zenml/image_builders/local_image_builder.py +13 -3
- zenml/integrations/__init__.py +1 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +14 -6
- zenml/integrations/constants.py +1 -0
- zenml/integrations/feast/__init__.py +1 -1
- zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -9
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +54 -9
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +65 -3
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +14 -2
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +6 -5
- zenml/integrations/kubernetes/service_connectors/kubernetes_service_connector.py +2 -1
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +3 -1
- zenml/integrations/modal/__init__.py +46 -0
- zenml/integrations/modal/flavors/__init__.py +26 -0
- zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
- zenml/integrations/modal/step_operators/__init__.py +22 -0
- zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
- zenml/io/filesystem.py +2 -2
- zenml/io/local_filesystem.py +3 -3
- zenml/materializers/built_in_materializer.py +18 -1
- zenml/materializers/structured_string_materializer.py +8 -3
- zenml/model/model.py +11 -85
- zenml/model/utils.py +18 -16
- zenml/models/__init__.py +12 -1
- zenml/models/v2/core/artifact_version.py +6 -3
- zenml/models/v2/core/component.py +0 -22
- zenml/models/v2/core/model_version.py +6 -3
- zenml/models/v2/core/pipeline_run.py +19 -3
- zenml/models/v2/core/run_metadata.py +30 -9
- zenml/models/v2/core/service_connector.py +4 -0
- zenml/models/v2/core/step_run.py +6 -4
- zenml/models/v2/misc/run_metadata.py +38 -0
- zenml/models/v2/misc/server_models.py +23 -0
- zenml/orchestrators/input_utils.py +19 -6
- zenml/orchestrators/publish_utils.py +12 -5
- zenml/orchestrators/step_launcher.py +7 -3
- zenml/orchestrators/step_run_utils.py +26 -9
- zenml/orchestrators/step_runner.py +40 -3
- zenml/orchestrators/utils.py +24 -23
- zenml/pipelines/pipeline_decorator.py +4 -0
- zenml/pipelines/pipeline_definition.py +26 -8
- zenml/pipelines/run_utils.py +9 -5
- zenml/steps/base_step.py +11 -1
- zenml/steps/entrypoint_function_utils.py +7 -3
- zenml/steps/step_decorator.py +4 -0
- zenml/steps/utils.py +23 -7
- zenml/types.py +4 -0
- zenml/utils/metadata_utils.py +186 -153
- zenml/utils/string_utils.py +41 -16
- zenml/utils/visualization_utils.py +4 -1
- zenml/zen_server/cloud_utils.py +3 -1
- zenml/zen_server/deploy/helm/templates/_environment.tpl +117 -0
- zenml/zen_server/deploy/helm/templates/server-db-job.yaml +3 -14
- zenml/zen_server/deploy/helm/templates/server-deployment.yaml +16 -4
- zenml/zen_server/deploy/helm/templates/server-secret.yaml +2 -17
- zenml/zen_server/rbac/endpoint_utils.py +6 -4
- zenml/zen_server/rbac/models.py +3 -2
- zenml/zen_server/rbac/utils.py +4 -7
- zenml/zen_server/routers/server_endpoints.py +47 -0
- zenml/zen_server/routers/users_endpoints.py +35 -37
- zenml/zen_server/routers/workspaces_endpoints.py +44 -55
- zenml/zen_server/template_execution/utils.py +1 -0
- zenml/zen_server/zen_server_api.py +45 -6
- zenml/zen_stores/migrations/utils.py +40 -24
- zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
- zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +7 -6
- zenml/zen_stores/rest_zen_store.py +38 -1
- zenml/zen_stores/schemas/__init__.py +5 -1
- zenml/zen_stores/schemas/artifact_schemas.py +12 -11
- zenml/zen_stores/schemas/component_schemas.py +0 -3
- zenml/zen_stores/schemas/model_schemas.py +13 -11
- zenml/zen_stores/schemas/pipeline_run_schemas.py +44 -16
- zenml/zen_stores/schemas/run_metadata_schemas.py +66 -31
- zenml/zen_stores/schemas/step_run_schemas.py +32 -12
- zenml/zen_stores/schemas/utils.py +47 -3
- zenml/zen_stores/sql_zen_store.py +130 -34
- {zenml_nightly-0.70.0.dev20241122.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/METADATA +1 -1
- {zenml_nightly-0.70.0.dev20241122.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/RECORD +102 -95
- zenml/utils/cloud_utils.py +0 -40
- {zenml_nightly-0.70.0.dev20241122.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.70.0.dev20241122.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.70.0.dev20241122.dist-info → zenml_nightly-0.70.0.dev20241201.dist-info}/entry_points.txt +0 -0
zenml/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.70.0.
|
1
|
+
0.70.0.dev20241201
|
@@ -267,11 +267,11 @@ class BaseArtifactStore(StackComponent):
|
|
267
267
|
|
268
268
|
# --- User interface ---
|
269
269
|
@abstractmethod
|
270
|
-
def open(self,
|
270
|
+
def open(self, path: PathType, mode: str = "r") -> Any:
|
271
271
|
"""Open a file at the given path.
|
272
272
|
|
273
273
|
Args:
|
274
|
-
|
274
|
+
path: The path of the file to open.
|
275
275
|
mode: The mode to open the file.
|
276
276
|
|
277
277
|
Returns:
|
@@ -45,7 +45,13 @@ class ArtifactConfig(BaseModel):
|
|
45
45
|
```
|
46
46
|
|
47
47
|
Attributes:
|
48
|
-
name: The name of the artifact
|
48
|
+
name: The name of the artifact:
|
49
|
+
- static string e.g. "name"
|
50
|
+
- dynamic string e.g. "name_{date}_{time}_{custom_placeholder}"
|
51
|
+
If you use any placeholders besides `date` and `time`,
|
52
|
+
you need to provide the values for them in the `substitutions`
|
53
|
+
argument of the step decorator or the `substitutions` argument
|
54
|
+
of `with_options` of the step.
|
49
55
|
version: The version of the artifact.
|
50
56
|
tags: The tags of the artifact.
|
51
57
|
run_metadata: Metadata to add to the artifact.
|
zenml/artifacts/utils.py
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
"""Utility functions for handling artifacts."""
|
15
15
|
|
16
16
|
import base64
|
17
|
+
import contextlib
|
17
18
|
import os
|
18
19
|
import tempfile
|
19
20
|
import zipfile
|
@@ -41,7 +42,6 @@ from zenml.enums import (
|
|
41
42
|
ArtifactSaveType,
|
42
43
|
ArtifactType,
|
43
44
|
ExecutionStatus,
|
44
|
-
MetadataResourceTypes,
|
45
45
|
StackComponentType,
|
46
46
|
VisualizationType,
|
47
47
|
)
|
@@ -404,50 +404,71 @@ def log_artifact_metadata(
|
|
404
404
|
artifact_version: The version of the artifact to log metadata for. If
|
405
405
|
not provided, when being called inside a step that produces an
|
406
406
|
artifact named `artifact_name`, the metadata will be associated to
|
407
|
-
the corresponding newly created artifact.
|
408
|
-
being called outside a step, or in a step that does not produce
|
409
|
-
any artifact named `artifact_name`, the metadata will be associated
|
410
|
-
to the latest version of that artifact.
|
407
|
+
the corresponding newly created artifact.
|
411
408
|
|
412
409
|
Raises:
|
413
410
|
ValueError: If no artifact name is provided and the function is not
|
414
411
|
called inside a step with a single output, or, if neither an
|
415
412
|
artifact nor an output with the given name exists.
|
413
|
+
|
416
414
|
"""
|
417
415
|
logger.warning(
|
418
416
|
"The `log_artifact_metadata` function is deprecated and will soon be "
|
419
417
|
"removed. Please use `log_metadata` instead."
|
420
418
|
)
|
421
|
-
|
419
|
+
|
420
|
+
from zenml import log_metadata
|
421
|
+
|
422
|
+
if artifact_name and artifact_version:
|
423
|
+
assert artifact_name is not None
|
424
|
+
|
425
|
+
log_metadata(
|
426
|
+
metadata=metadata,
|
427
|
+
artifact_name=artifact_name,
|
428
|
+
artifact_version=artifact_version,
|
429
|
+
)
|
430
|
+
|
431
|
+
step_context = None
|
432
|
+
with contextlib.suppress(RuntimeError):
|
422
433
|
step_context = get_step_context()
|
423
|
-
|
424
|
-
|
434
|
+
|
435
|
+
if step_context and artifact_name in step_context._outputs.keys():
|
436
|
+
log_metadata(
|
437
|
+
metadata=metadata,
|
438
|
+
artifact_name=artifact_name,
|
439
|
+
infer_artifact=True,
|
425
440
|
)
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
)
|
441
|
+
elif step_context and len(step_context._outputs) == 1:
|
442
|
+
single_output_name = list(step_context._outputs.keys())[0]
|
443
|
+
|
444
|
+
log_metadata(
|
445
|
+
metadata=metadata,
|
446
|
+
artifact_name=single_output_name,
|
447
|
+
infer_artifact=True,
|
448
|
+
)
|
449
|
+
elif artifact_name:
|
436
450
|
client = Client()
|
437
|
-
|
438
|
-
|
451
|
+
logger.warning(
|
452
|
+
"Deprecation warning! Currently, you are calling "
|
453
|
+
"`log_artifact_metadata` from a context, where we use the "
|
454
|
+
"`artifact_name` to fetch it and link the metadata to its "
|
455
|
+
"latest version. This behavior is deprecated and will be "
|
456
|
+
"removed in the future. To circumvent this, please check"
|
457
|
+
"the `log_metadata` function."
|
458
|
+
)
|
459
|
+
artifact_version_model = client.get_artifact_version(
|
460
|
+
name_id_or_prefix=artifact_name
|
461
|
+
)
|
462
|
+
log_metadata(
|
439
463
|
metadata=metadata,
|
440
|
-
|
441
|
-
resource_type=MetadataResourceTypes.ARTIFACT_VERSION,
|
464
|
+
artifact_version_id=artifact_version_model.id,
|
442
465
|
)
|
443
|
-
|
444
466
|
else:
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
)
|
449
|
-
|
450
|
-
raise ValueError(e)
|
467
|
+
raise ValueError(
|
468
|
+
"You need to call `log_artifact_metadata` either within a step "
|
469
|
+
"(potentially with an artifact name) or outside of a step with an "
|
470
|
+
"artifact name (and/or version)."
|
471
|
+
)
|
451
472
|
|
452
473
|
|
453
474
|
# -----------------
|
@@ -575,7 +596,7 @@ def download_artifact_files_from_response(
|
|
575
596
|
)
|
576
597
|
file_path = str(Path(artifact.uri) / file_str)
|
577
598
|
with artifact_store.open(
|
578
|
-
|
599
|
+
file_path, mode="rb"
|
579
600
|
) as store_file:
|
580
601
|
# Use a loop to read and write chunks of the file
|
581
602
|
# instead of reading the entire file into memory
|
@@ -689,7 +710,11 @@ def _link_artifact_version_to_the_step_and_model(
|
|
689
710
|
client.zen_store.update_run_step(
|
690
711
|
step_run_id=step_run.id,
|
691
712
|
step_run_update=StepRunUpdate(
|
692
|
-
outputs={
|
713
|
+
outputs={
|
714
|
+
artifact_version.artifact.name: [
|
715
|
+
artifact_version.id,
|
716
|
+
]
|
717
|
+
}
|
693
718
|
),
|
694
719
|
)
|
695
720
|
error_message = "model"
|
zenml/cli/__init__.py
CHANGED
@@ -2242,6 +2242,9 @@ export ZENML_STORE_URL=https://...
|
|
2242
2242
|
export ZENML_STORE_API_KEY=<API_KEY>
|
2243
2243
|
```
|
2244
2244
|
|
2245
|
+
You don't need to run `zenml login` after setting these two environment
|
2246
|
+
variables and can start interacting with your server right away.
|
2247
|
+
|
2245
2248
|
To see all the service accounts you've created and their API keys, use the
|
2246
2249
|
following commands:
|
2247
2250
|
|
@@ -2407,6 +2410,21 @@ stack, use the `--stack` option.
|
|
2407
2410
|
zenml pipeline run <PIPELINE_SOURCE_PATH> --stack=<STACK_ID_OR_NAME>
|
2408
2411
|
```
|
2409
2412
|
|
2413
|
+
If you want to create a run template based on your pipeline that can later be used to trigger a run either from the dashboard or through an HTTP request:
|
2414
|
+
|
2415
|
+
```bash
|
2416
|
+
zenml pipeline create-run-template <PIPELINE_SOURCE_PATH> \
|
2417
|
+
--name=<TEMPLATE_NAME>
|
2418
|
+
|
2419
|
+
To specify a config file, use the `--config/-c` option. If you would like to use a different stack than the active one, use the `--stack` option.
|
2420
|
+
|
2421
|
+
```bash
|
2422
|
+
zenml pipeline create-run-template <PIPELINE_SOURCE_PATH> \
|
2423
|
+
--name=<TEMPLATE_NAME> \
|
2424
|
+
--config=<PATH_TO_CONFIG_YAML> \
|
2425
|
+
--stack=<STACK_ID_OR_NAME>
|
2426
|
+
```
|
2427
|
+
|
2410
2428
|
Tagging your resources with ZenML
|
2411
2429
|
---------------------------------
|
2412
2430
|
|
zenml/cli/base.py
CHANGED
@@ -79,19 +79,19 @@ class ZenMLProjectTemplateLocation(BaseModel):
|
|
79
79
|
ZENML_PROJECT_TEMPLATES = dict(
|
80
80
|
e2e_batch=ZenMLProjectTemplateLocation(
|
81
81
|
github_url="zenml-io/template-e2e-batch",
|
82
|
-
github_tag="2024.11.
|
82
|
+
github_tag="2024.11.28", # Make sure it is aligned with .github/workflows/update-templates-to-examples.yml
|
83
83
|
),
|
84
84
|
starter=ZenMLProjectTemplateLocation(
|
85
85
|
github_url="zenml-io/template-starter",
|
86
|
-
github_tag="2024.
|
86
|
+
github_tag="2024.11.28", # Make sure it is aligned with .github/workflows/update-templates-to-examples.yml
|
87
87
|
),
|
88
88
|
nlp=ZenMLProjectTemplateLocation(
|
89
89
|
github_url="zenml-io/template-nlp",
|
90
|
-
github_tag="2024.
|
90
|
+
github_tag="2024.11.28", # Make sure it is aligned with .github/workflows/update-templates-to-examples.yml
|
91
91
|
),
|
92
92
|
llm_finetuning=ZenMLProjectTemplateLocation(
|
93
93
|
github_url="zenml-io/template-llm-finetuning",
|
94
|
-
github_tag="2024.11.
|
94
|
+
github_tag="2024.11.28", # Make sure it is aligned with .github/workflows/update-templates-to-examples.yml
|
95
95
|
),
|
96
96
|
)
|
97
97
|
|
zenml/cli/login.py
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
"""CLI for managing ZenML server deployments."""
|
15
15
|
|
16
16
|
import ipaddress
|
17
|
+
import os
|
17
18
|
import re
|
18
19
|
import sys
|
19
20
|
import time
|
@@ -413,6 +414,27 @@ def connect_to_pro_server(
|
|
413
414
|
cli_utils.declare(f"Connected to ZenML Pro server: {server.name}.")
|
414
415
|
|
415
416
|
|
417
|
+
def _fail_if_authentication_environment_variables_set() -> None:
|
418
|
+
"""Fail if any of the authentication environment variables are set."""
|
419
|
+
environment_variables = [
|
420
|
+
"ZENML_STORE_URL",
|
421
|
+
"ZENML_STORE_API_KEY",
|
422
|
+
"ZENML_STORE_USERNAME",
|
423
|
+
"ZENML_STORE_PASSWORD",
|
424
|
+
]
|
425
|
+
|
426
|
+
if any(env_var in os.environ for env_var in environment_variables):
|
427
|
+
cli_utils.error(
|
428
|
+
"You're running to login/logout while having one of the "
|
429
|
+
f"{environment_variables} environment variables set. "
|
430
|
+
"If you want to use those environment variables to authenticate "
|
431
|
+
"to your ZenML server, there is no need to login/logout, you can "
|
432
|
+
"start interacting with your server right away. If you want to use "
|
433
|
+
"the `zenml login` command for authentication, please unset these "
|
434
|
+
"environment variables first."
|
435
|
+
)
|
436
|
+
|
437
|
+
|
416
438
|
@cli.command(
|
417
439
|
"login",
|
418
440
|
help=(
|
@@ -670,6 +692,8 @@ def login(
|
|
670
692
|
dashboard on a public domain. Primarily used for accessing the
|
671
693
|
dashboard in Colab.
|
672
694
|
"""
|
695
|
+
_fail_if_authentication_environment_variables_set()
|
696
|
+
|
673
697
|
if local:
|
674
698
|
if api_key:
|
675
699
|
cli_utils.error(
|
@@ -849,6 +873,8 @@ def logout(
|
|
849
873
|
"""
|
850
874
|
from zenml.login.credentials_store import get_credentials_store
|
851
875
|
|
876
|
+
_fail_if_authentication_environment_variables_set()
|
877
|
+
|
852
878
|
credentials_store = get_credentials_store()
|
853
879
|
gc = GlobalConfiguration()
|
854
880
|
store_cfg = gc.store_configuration
|
zenml/cli/pipeline.py
CHANGED
@@ -315,6 +315,86 @@ def run_pipeline(
|
|
315
315
|
pipeline_instance()
|
316
316
|
|
317
317
|
|
318
|
+
@pipeline.command(
|
319
|
+
"create-run-template",
|
320
|
+
help="Create a run template for a pipeline. The SOURCE argument needs to "
|
321
|
+
"be an importable source path resolving to a ZenML pipeline instance, e.g. "
|
322
|
+
"`my_module.my_pipeline_instance`.",
|
323
|
+
)
|
324
|
+
@click.argument("source")
|
325
|
+
@click.option(
|
326
|
+
"--name",
|
327
|
+
"-n",
|
328
|
+
type=str,
|
329
|
+
required=True,
|
330
|
+
help="Name for the template",
|
331
|
+
)
|
332
|
+
@click.option(
|
333
|
+
"--config",
|
334
|
+
"-c",
|
335
|
+
"config_path",
|
336
|
+
type=click.Path(exists=True, dir_okay=False),
|
337
|
+
required=False,
|
338
|
+
help="Path to configuration file for the build.",
|
339
|
+
)
|
340
|
+
@click.option(
|
341
|
+
"--stack",
|
342
|
+
"-s",
|
343
|
+
"stack_name_or_id",
|
344
|
+
type=str,
|
345
|
+
required=False,
|
346
|
+
help="Name or ID of the stack to use for the build.",
|
347
|
+
)
|
348
|
+
def create_run_template(
|
349
|
+
source: str,
|
350
|
+
name: str,
|
351
|
+
config_path: Optional[str] = None,
|
352
|
+
stack_name_or_id: Optional[str] = None,
|
353
|
+
) -> None:
|
354
|
+
"""Create a run template for a pipeline.
|
355
|
+
|
356
|
+
Args:
|
357
|
+
source: Importable source resolving to a pipeline instance.
|
358
|
+
name: Name of the run template.
|
359
|
+
config_path: Path to pipeline configuration file.
|
360
|
+
stack_name_or_id: Name or ID of the stack for which the template should
|
361
|
+
be created.
|
362
|
+
"""
|
363
|
+
if not Client().root:
|
364
|
+
cli_utils.warning(
|
365
|
+
"You're running the `zenml pipeline create-run-template` command "
|
366
|
+
"without a ZenML repository. Your current working directory will "
|
367
|
+
"be used as the source root relative to which the registered step "
|
368
|
+
"classes will be resolved. To silence this warning, run `zenml "
|
369
|
+
"init` at your source code root."
|
370
|
+
)
|
371
|
+
|
372
|
+
try:
|
373
|
+
pipeline_instance = source_utils.load(source)
|
374
|
+
except ModuleNotFoundError as e:
|
375
|
+
source_root = source_utils.get_source_root()
|
376
|
+
cli_utils.error(
|
377
|
+
f"Unable to import module `{e.name}`. Make sure the source path is "
|
378
|
+
f"relative to your source root `{source_root}`."
|
379
|
+
)
|
380
|
+
except AttributeError as e:
|
381
|
+
cli_utils.error("Unable to load attribute from module: " + str(e))
|
382
|
+
|
383
|
+
if not isinstance(pipeline_instance, Pipeline):
|
384
|
+
cli_utils.error(
|
385
|
+
f"The given source path `{source}` does not resolve to a pipeline "
|
386
|
+
"object."
|
387
|
+
)
|
388
|
+
|
389
|
+
with cli_utils.temporary_active_stack(stack_name_or_id=stack_name_or_id):
|
390
|
+
pipeline_instance = pipeline_instance.with_options(
|
391
|
+
config_path=config_path
|
392
|
+
)
|
393
|
+
template = pipeline_instance.create_run_template(name=name)
|
394
|
+
|
395
|
+
cli_utils.declare(f"Created run template `{template.id}`.")
|
396
|
+
|
397
|
+
|
318
398
|
@pipeline.command("list", help="List all registered pipelines.")
|
319
399
|
@list_options(PipelineFilter)
|
320
400
|
def list_pipelines(**kwargs: Any) -> None:
|
zenml/cli/server.py
CHANGED
@@ -469,7 +469,7 @@ def logs(
|
|
469
469
|
if server is None:
|
470
470
|
cli_utils.error(
|
471
471
|
"The local ZenML dashboard is not running. Please call `zenml "
|
472
|
-
"
|
472
|
+
"login --local` first to start the ZenML dashboard locally."
|
473
473
|
)
|
474
474
|
|
475
475
|
from zenml.zen_server.deploy.deployer import LocalServerDeployer
|
zenml/cli/service_connectors.py
CHANGED
@@ -1194,9 +1194,9 @@ to provide access to:
|
|
1194
1194
|
use from an STS token to an AWS secret key. This involves updating some config
|
1195
1195
|
values and deleting others:
|
1196
1196
|
|
1197
|
-
$ zenml service-connector update aws-auto-multi \\
|
1198
|
-
--
|
1199
|
-
--aws_secret_access_key=<aws-secret-key> \\
|
1197
|
+
$ zenml service-connector update aws-auto-multi \\
|
1198
|
+
--aws_access_key_id=<aws-key-id> \\
|
1199
|
+
--aws_secret_access_key=<aws-secret-key> \\
|
1200
1200
|
--remove-attr aws-sts-token
|
1201
1201
|
|
1202
1202
|
- update the foo label to a new value and delete the baz label from a connector:
|
zenml/cli/stack.py
CHANGED
@@ -1129,14 +1129,12 @@ def export_stack(
|
|
1129
1129
|
def _import_stack_component(
|
1130
1130
|
component_type: StackComponentType,
|
1131
1131
|
component_dict: Dict[str, Any],
|
1132
|
-
component_spec_path: Optional[str] = None,
|
1133
1132
|
) -> UUID:
|
1134
1133
|
"""Import a single stack component with given type/config.
|
1135
1134
|
|
1136
1135
|
Args:
|
1137
1136
|
component_type: The type of component to import.
|
1138
1137
|
component_dict: Dict representation of the component to import.
|
1139
|
-
component_spec_path: Path to the component spec file.
|
1140
1138
|
|
1141
1139
|
Returns:
|
1142
1140
|
The ID of the imported component.
|
@@ -1172,7 +1170,6 @@ def _import_stack_component(
|
|
1172
1170
|
component_type=component_type,
|
1173
1171
|
flavor=flavor,
|
1174
1172
|
configuration=config,
|
1175
|
-
component_spec_path=component_spec_path,
|
1176
1173
|
)
|
1177
1174
|
return component.id
|
1178
1175
|
|
zenml/cli/stack_components.py
CHANGED
@@ -573,7 +573,6 @@ def generate_stack_component_copy_command(
|
|
573
573
|
component_type=component_to_copy.type,
|
574
574
|
configuration=component_to_copy.configuration,
|
575
575
|
labels=component_to_copy.labels,
|
576
|
-
component_spec_path=component_to_copy.component_spec_path,
|
577
576
|
)
|
578
577
|
print_model_url(get_component_url(copied_component))
|
579
578
|
|
zenml/cli/utils.py
CHANGED
@@ -711,11 +711,6 @@ def print_stack_component_configuration(
|
|
711
711
|
|
712
712
|
console.print(rich_table)
|
713
713
|
|
714
|
-
if component.component_spec_path:
|
715
|
-
declare(
|
716
|
-
f"Component spec path for `mlstacks`: {component.component_spec_path}"
|
717
|
-
)
|
718
|
-
|
719
714
|
|
720
715
|
def expand_argument_value_from_file(name: str, value: str) -> str:
|
721
716
|
"""Expands the value of an argument pointing to a file into the contents of that file.
|
zenml/client.py
CHANGED
@@ -60,7 +60,6 @@ from zenml.constants import (
|
|
60
60
|
from zenml.enums import (
|
61
61
|
ArtifactType,
|
62
62
|
LogicalOperators,
|
63
|
-
MetadataResourceTypes,
|
64
63
|
ModelStages,
|
65
64
|
OAuthDeviceStatus,
|
66
65
|
PluginSubType,
|
@@ -137,6 +136,7 @@ from zenml.models import (
|
|
137
136
|
PipelineRunFilter,
|
138
137
|
PipelineRunResponse,
|
139
138
|
RunMetadataRequest,
|
139
|
+
RunMetadataResource,
|
140
140
|
RunTemplateFilter,
|
141
141
|
RunTemplateRequest,
|
142
142
|
RunTemplateResponse,
|
@@ -1979,7 +1979,6 @@ class Client(metaclass=ClientMetaClass):
|
|
1979
1979
|
flavor: str,
|
1980
1980
|
component_type: StackComponentType,
|
1981
1981
|
configuration: Dict[str, str],
|
1982
|
-
component_spec_path: Optional[str] = None,
|
1983
1982
|
labels: Optional[Dict[str, Any]] = None,
|
1984
1983
|
) -> "ComponentResponse":
|
1985
1984
|
"""Registers a stack component.
|
@@ -1987,7 +1986,6 @@ class Client(metaclass=ClientMetaClass):
|
|
1987
1986
|
Args:
|
1988
1987
|
name: The name of the stack component.
|
1989
1988
|
flavor: The flavor of the stack component.
|
1990
|
-
component_spec_path: The path to the stack spec file.
|
1991
1989
|
component_type: The type of the stack component.
|
1992
1990
|
configuration: The configuration of the stack component.
|
1993
1991
|
labels: The labels of the stack component.
|
@@ -2016,7 +2014,6 @@ class Client(metaclass=ClientMetaClass):
|
|
2016
2014
|
name=name,
|
2017
2015
|
type=component_type,
|
2018
2016
|
flavor=flavor,
|
2019
|
-
component_spec_path=component_spec_path,
|
2020
2017
|
configuration=configuration,
|
2021
2018
|
user=self.active_user.id,
|
2022
2019
|
workspace=self.active_workspace.id,
|
@@ -2033,7 +2030,6 @@ class Client(metaclass=ClientMetaClass):
|
|
2033
2030
|
name_id_or_prefix: Optional[Union[UUID, str]],
|
2034
2031
|
component_type: StackComponentType,
|
2035
2032
|
name: Optional[str] = None,
|
2036
|
-
component_spec_path: Optional[str] = None,
|
2037
2033
|
configuration: Optional[Dict[str, Any]] = None,
|
2038
2034
|
labels: Optional[Dict[str, Any]] = None,
|
2039
2035
|
disconnect: Optional[bool] = None,
|
@@ -2047,7 +2043,6 @@ class Client(metaclass=ClientMetaClass):
|
|
2047
2043
|
update.
|
2048
2044
|
component_type: The type of the stack component to update.
|
2049
2045
|
name: The new name of the stack component.
|
2050
|
-
component_spec_path: The new path to the stack spec file.
|
2051
2046
|
configuration: The new configuration of the stack component.
|
2052
2047
|
labels: The new labels of the stack component.
|
2053
2048
|
disconnect: Whether to disconnect the stack component from its
|
@@ -2072,7 +2067,6 @@ class Client(metaclass=ClientMetaClass):
|
|
2072
2067
|
update_model = ComponentUpdate(
|
2073
2068
|
workspace=self.active_workspace.id,
|
2074
2069
|
user=self.active_user.id,
|
2075
|
-
component_spec_path=component_spec_path,
|
2076
2070
|
)
|
2077
2071
|
|
2078
2072
|
if name is not None:
|
@@ -4438,23 +4432,20 @@ class Client(metaclass=ClientMetaClass):
|
|
4438
4432
|
def create_run_metadata(
|
4439
4433
|
self,
|
4440
4434
|
metadata: Dict[str, "MetadataType"],
|
4441
|
-
|
4442
|
-
resource_type: MetadataResourceTypes,
|
4435
|
+
resources: List[RunMetadataResource],
|
4443
4436
|
stack_component_id: Optional[UUID] = None,
|
4437
|
+
publisher_step_id: Optional[UUID] = None,
|
4444
4438
|
) -> None:
|
4445
4439
|
"""Create run metadata.
|
4446
4440
|
|
4447
4441
|
Args:
|
4448
4442
|
metadata: The metadata to create as a dictionary of key-value pairs.
|
4449
|
-
|
4450
|
-
metadata was produced.
|
4451
|
-
resource_type: The type of the resource for which the
|
4443
|
+
resources: The list of IDs and types of the resources for that the
|
4452
4444
|
metadata was produced.
|
4453
4445
|
stack_component_id: The ID of the stack component that produced
|
4454
4446
|
the metadata.
|
4455
|
-
|
4456
|
-
|
4457
|
-
None
|
4447
|
+
publisher_step_id: The ID of the step execution that publishes
|
4448
|
+
this metadata automatically.
|
4458
4449
|
"""
|
4459
4450
|
from zenml.metadata.metadata_types import get_metadata_type
|
4460
4451
|
|
@@ -4483,14 +4474,13 @@ class Client(metaclass=ClientMetaClass):
|
|
4483
4474
|
run_metadata = RunMetadataRequest(
|
4484
4475
|
workspace=self.active_workspace.id,
|
4485
4476
|
user=self.active_user.id,
|
4486
|
-
|
4487
|
-
resource_type=resource_type,
|
4477
|
+
resources=resources,
|
4488
4478
|
stack_component_id=stack_component_id,
|
4479
|
+
publisher_step_id=publisher_step_id,
|
4489
4480
|
values=values,
|
4490
4481
|
types=types,
|
4491
4482
|
)
|
4492
4483
|
self.zen_store.create_run_metadata(run_metadata)
|
4493
|
-
return None
|
4494
4484
|
|
4495
4485
|
# -------------------------------- Secrets ---------------------------------
|
4496
4486
|
|
zenml/config/compiler.py
CHANGED
@@ -99,7 +99,10 @@ class Compiler:
|
|
99
99
|
|
100
100
|
self._apply_stack_default_settings(pipeline=pipeline, stack=stack)
|
101
101
|
if run_configuration.run_name:
|
102
|
-
self._verify_run_name(
|
102
|
+
self._verify_run_name(
|
103
|
+
run_configuration.run_name,
|
104
|
+
pipeline.configuration.substitutions,
|
105
|
+
)
|
103
106
|
|
104
107
|
pipeline_settings = self._filter_and_validate_settings(
|
105
108
|
settings=pipeline.configuration.settings,
|
@@ -305,16 +308,22 @@ class Compiler:
|
|
305
308
|
return default_settings
|
306
309
|
|
307
310
|
@staticmethod
|
308
|
-
def _verify_run_name(
|
311
|
+
def _verify_run_name(
|
312
|
+
run_name: str,
|
313
|
+
substitutions: Dict[str, str],
|
314
|
+
) -> None:
|
309
315
|
"""Verifies that the run name contains only valid placeholders.
|
310
316
|
|
311
317
|
Args:
|
312
318
|
run_name: The run name to verify.
|
319
|
+
substitutions: The substitutions to be used in the run name.
|
313
320
|
|
314
321
|
Raises:
|
315
322
|
ValueError: If the run name contains invalid placeholders.
|
316
323
|
"""
|
317
|
-
valid_placeholder_names = {"date", "time"}
|
324
|
+
valid_placeholder_names = {"date", "time"}.union(
|
325
|
+
set(substitutions.keys())
|
326
|
+
)
|
318
327
|
placeholders = {
|
319
328
|
v[1] for v in string.Formatter().parse(run_name) if v[1]
|
320
329
|
}
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Pipeline configuration classes."""
|
15
15
|
|
16
|
+
from datetime import datetime
|
16
17
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
17
18
|
|
18
19
|
from pydantic import SerializeAsAny, field_validator
|
@@ -46,6 +47,25 @@ class PipelineConfigurationUpdate(StrictBaseModel):
|
|
46
47
|
model: Optional[Model] = None
|
47
48
|
parameters: Optional[Dict[str, Any]] = None
|
48
49
|
retry: Optional[StepRetryConfig] = None
|
50
|
+
substitutions: Dict[str, str] = {}
|
51
|
+
|
52
|
+
def _get_full_substitutions(
|
53
|
+
self, start_time: Optional[datetime]
|
54
|
+
) -> Dict[str, str]:
|
55
|
+
"""Returns the full substitutions dict.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
start_time: Start time of the pipeline run.
|
59
|
+
|
60
|
+
Returns:
|
61
|
+
The full substitutions dict including date and time.
|
62
|
+
"""
|
63
|
+
if start_time is None:
|
64
|
+
start_time = datetime.utcnow()
|
65
|
+
ret = self.substitutions.copy()
|
66
|
+
ret.setdefault("date", start_time.strftime("%Y_%m_%d"))
|
67
|
+
ret.setdefault("time", start_time.strftime("%H_%M_%S_%f"))
|
68
|
+
return ret
|
49
69
|
|
50
70
|
|
51
71
|
class PipelineConfiguration(PipelineConfigurationUpdate):
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# permissions and limitations under the License.
|
14
14
|
"""Pipeline configuration classes."""
|
15
15
|
|
16
|
+
from datetime import datetime
|
16
17
|
from typing import (
|
17
18
|
TYPE_CHECKING,
|
18
19
|
Any,
|
@@ -49,6 +50,7 @@ from zenml.utils.pydantic_utils import before_validator_handler
|
|
49
50
|
|
50
51
|
if TYPE_CHECKING:
|
51
52
|
from zenml.config import DockerSettings, ResourceSettings
|
53
|
+
from zenml.config.pipeline_configurations import PipelineConfiguration
|
52
54
|
|
53
55
|
logger = get_logger(__name__)
|
54
56
|
|
@@ -152,6 +154,7 @@ class StepConfigurationUpdate(StrictBaseModel):
|
|
152
154
|
success_hook_source: Optional[SourceWithValidator] = None
|
153
155
|
model: Optional[Model] = None
|
154
156
|
retry: Optional[StepRetryConfig] = None
|
157
|
+
substitutions: Dict[str, str] = {}
|
155
158
|
|
156
159
|
outputs: Mapping[str, PartialArtifactConfiguration] = {}
|
157
160
|
|
@@ -237,6 +240,24 @@ class StepConfiguration(PartialStepConfiguration):
|
|
237
240
|
model_or_dict = model_or_dict.model_dump()
|
238
241
|
return DockerSettings.model_validate(model_or_dict)
|
239
242
|
|
243
|
+
def _get_full_substitutions(
|
244
|
+
self,
|
245
|
+
pipeline_config: "PipelineConfiguration",
|
246
|
+
start_time: Optional[datetime],
|
247
|
+
) -> Dict[str, str]:
|
248
|
+
"""Get the full set of substitutions for this step configuration.
|
249
|
+
|
250
|
+
Args:
|
251
|
+
pipeline_config: The pipeline configuration.
|
252
|
+
start_time: The start time of the pipeline run.
|
253
|
+
|
254
|
+
Returns:
|
255
|
+
The full set of substitutions for this step configuration.
|
256
|
+
"""
|
257
|
+
ret = pipeline_config._get_full_substitutions(start_time)
|
258
|
+
ret.update(self.substitutions)
|
259
|
+
return ret
|
260
|
+
|
240
261
|
|
241
262
|
class InputSpec(StrictBaseModel):
|
242
263
|
"""Step input specification."""
|