Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Active Stack as part of configuration YAML #2370

Open
wants to merge 38 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
60af95f
add active_stack to run_config
kabinja Jan 29, 2024
ac820e5
remove test generated file
kabinja Jan 29, 2024
9f76559
fix typos
kabinja Jan 29, 2024
fd1f482
fix typo
kabinja Jan 29, 2024
63bc189
Merge branch 'develop' into feature/config-active-stack
strickvl Jan 31, 2024
a98112c
Update src/zenml/new/pipelines/pipeline.py
kabinja Feb 2, 2024
c2d7774
Update src/zenml/stack/utils.py
kabinja Feb 2, 2024
8242efb
fix doc string for __exit__ method of stack_context
kabinja Feb 4, 2024
f075c4a
Merge branch 'develop' into feature/config-active-stack
kabinja Feb 4, 2024
fbe12e0
fix linting
kabinja Feb 4, 2024
80a578d
add documentation
kabinja Feb 4, 2024
120885a
Merge branch 'develop' into feature/config-active-stack
strickvl Feb 5, 2024
001a031
Update docs/book/user-guide/advanced-guide/pipelining-features/config…
kabinja Feb 5, 2024
323d33c
Update docs/book/user-guide/advanced-guide/pipelining-features/config…
kabinja Feb 5, 2024
8959f07
Update src/zenml/stack/utils.py
kabinja Feb 5, 2024
dfc3115
Update src/zenml/stack/utils.py
kabinja Feb 5, 2024
f141fed
update TOC (#2406)
strickvl Feb 6, 2024
2cdcfac
fix docstring indentation
kabinja Feb 6, 2024
590b074
Fix GCP service connector login to overwrite existing valid credentia…
stefannica Feb 5, 2024
b64fae9
Update `has_custom_name` for legacy artifacts (#2384)
avishniakov Feb 5, 2024
ce9a34f
Use native VertexAI scheduler capability instead of old GCP official …
francoisserra Feb 6, 2024
c1abd87
HyperAI integration: orchestrator and service connector (#2372)
christianversloot Feb 6, 2024
a0a12e8
Let contributors shield link to ZenML contributors (#2400)
christianversloot Feb 6, 2024
479b292
Prepare release 0.55.2 (#2401)
bcdurak Feb 6, 2024
e51297c
update TOC (#2406)
strickvl Feb 6, 2024
1022574
Merge branch 'develop' into feature/config-active-stack
kabinja Feb 6, 2024
855c96b
Merge branch 'develop' into feature/config-active-stack
strickvl Feb 7, 2024
4c284fe
ubuntu-dind-runners for release workflow
strickvl Feb 20, 2024
9865043
Merge branch 'zenml-io:main' into feature/config-active-stack
kabinja Feb 20, 2024
c34b389
fix bug comparing id in exit method
kabinja Feb 20, 2024
e27df0e
Merge branch 'develop' into feature/config-active-stack
strickvl Feb 23, 2024
876a9fb
rename active_stack to stack in pipeline run configuration
kabinja Feb 26, 2024
d07e90c
replace stack_context to use temporary_active_stack
kabinja Feb 26, 2024
5126923
Merge branch 'develop' into feature/config-active-stack
strickvl Feb 28, 2024
226791c
Merge branch 'develop' into feature/config-active-stack
strickvl Mar 13, 2024
7e72e00
Merge branch 'develop' into feature/config-active-stack
bcdurak Mar 13, 2024
951ea5b
temporary_active_stack
kabinja Mar 24, 2024
597ffbb
Merge branch 'develop' into feature/config-active-stack
strickvl Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ python run.py
<summary>An example of a generated YAML configuration template</summary>

```yaml
active_stack: Optional[str]
build: Union[PipelineBuildBase, UUID, NoneType]
enable_artifact_metadata: Optional[bool]
enable_artifact_visualization: Optional[bool]
Expand Down Expand Up @@ -330,6 +331,12 @@ These are boolean flags for various configurations:
* `enable_cache`: Utilize [caching](../../starter-guide/cache-previous-executions.md) or not.
* `enable_step_logs`: Enable tracking [step logs](managing-steps.md#enable-or-disable-logs-storing).

### `active_stack` name or ID

The name or the UUID of the `active stack` to use for this
pipeline. If specified, the active stack is set for the duration of the pipeline execution and restored upon
completion. If not specified, the current active stack is used.

### `build` ID

The UUID of the [`build`](../infrastructure-management/containerize-your-pipeline.md) to use for this pipeline. If specified, Docker image building is skipped for remote orchestrators, and the Docker image specified in this build is used.
Expand Down
1 change: 1 addition & 0 deletions src/zenml/config/pipeline_run_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PipelineRunConfiguration(
):
"""Class for pipeline run configurations."""

active_stack: Optional[str] = None
kabinja marked this conversation as resolved.
Show resolved Hide resolved
run_name: Optional[str] = None
enable_cache: Optional[bool] = None
enable_artifact_metadata: Optional[bool] = None
Expand Down
22 changes: 20 additions & 2 deletions src/zenml/new/pipelines/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
prepare_model_versions,
)
from zenml.stack import Stack
from zenml.stack.utils import stack_context
from zenml.steps import BaseStep
from zenml.steps.entrypoint_function_utils import (
StepArtifact,
Expand Down Expand Up @@ -536,7 +537,9 @@ def build(
Returns:
The build output.
"""
with track_handler(event=AnalyticsEvent.BUILD_PIPELINE):
with track_handler(
event=AnalyticsEvent.BUILD_PIPELINE
), stack_context():
self._prepare_if_possible()
deployment, pipeline_spec, _, _ = self._compile(
config_path=config_path,
Expand Down Expand Up @@ -619,7 +622,9 @@ def _run(

logger.info(f"Initiating a new run for the pipeline: `{self.name}`.")

with track_handler(AnalyticsEvent.RUN_PIPELINE) as analytics_handler:
with track_handler(
AnalyticsEvent.RUN_PIPELINE
) as analytics_handler, stack_context():
deployment, pipeline_spec, schedule, build = self._compile(
config_path=config_path,
run_name=run_name,
Expand Down Expand Up @@ -1014,6 +1019,8 @@ def _compile(
# Update with the values in code so they take precedence
run_config = pydantic_utils.update_model(run_config, update=update)

self._update_stack_from_config(run_config)

deployment, pipeline_spec = Compiler().compile(
pipeline=self,
stack=Client().active_stack,
Expand Down Expand Up @@ -1437,3 +1444,14 @@ def _prepare_if_possible(self) -> None:
)
else:
self.prepare()

def _update_stack_from_config(
self, run_configuration: PipelineRunConfiguration
) -> None:
"""Activate the stack from the pipeline run configuration if one is given.

Args:
run_configuration: The run configuration for this pipeline.
"""
if run_configuration.active_stack is not None:
Client().activate_stack(run_configuration.active_stack)
33 changes: 32 additions & 1 deletion src/zenml/stack/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# permissions and limitations under the License.
"""Util functions for handling stacks, components, and flavors."""

from typing import Any, Dict, Optional
from types import TracebackType
from typing import Any, Dict, Optional, Type

from zenml.client import Client
from zenml.enums import StackComponentType, StoreType
Expand Down Expand Up @@ -139,3 +140,33 @@ def get_flavor_by_name_and_type_from_zen_store(
f"'{component_type}' exists."
)
return flavors[0]


class stack_context:
kabinja marked this conversation as resolved.
Show resolved Hide resolved
"""Context handler to reset the original active stack."""

def __init__(self) -> None:
"""Constructor for stack_context saves active stack."""
self._default_stack = Client().active_stack

def __enter__(self) -> None:
"""Enters in the stack context."""
pass

def __exit__(
self,
exception_type: Optional[Type[BaseException]],
exception_value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
"""Get a stack component flavor by name and type from a ZenStore.

Args:
exception_type: Type of the exception that was raised.
None if no exception.
exception_value: Type of exception that was raised.
e.g., divide_by_zero error. None if no exception.
traceback: Traceback report. None if no exception.
"""
if self._default_stack.id != Client().active_stack.id:
Client().activate_stack(self._default_stack.id)
33 changes: 33 additions & 0 deletions tests/integration/functional/cli/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,39 @@ def test_pipeline_run_with_config_file(clean_client: "Client", tmp_path):
assert runs[0].name == "custom_run_name"


def test_pipeline_run_with_different_stack_in_config_file(
clean_client: "Client", tmp_path
):
"""Tests that the run command works with a run config file with an active stack defined."""
runner = CliRunner()
run_command = cli.commands["pipeline"].commands["run"]

pipeline_id = pipeline_instance.register().id

components = {
key: components[0].id
for key, components in Client().active_stack_model.components.items()
}
new_stack = Client().create_stack(name="new", components=components)

config_path = tmp_path / "config.yaml"
run_config = PipelineRunConfiguration(
run_name="custom_run_name", active_stack=str(new_stack.id)
)
config_path.write_text(run_config.yaml())

result = runner.invoke(
run_command, [pipeline_instance.name, "--config", str(config_path)]
)
assert result.exit_code == 0

runs = Client().list_pipeline_runs(pipeline_id=pipeline_id)
assert len(runs) == 1
assert runs[0].name == "custom_run_name"
assert runs[0].stack.id == new_stack.id
assert Client().active_stack.id != new_stack.id

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test test_pipeline_run_with_different_stack_in_config_file is well-implemented and effectively verifies that the pipeline run command correctly handles a different active stack specified in the run configuration file. This test ensures the new feature works as intended and is a valuable addition to the test suite. However, it would be beneficial to include assertions to verify that the active stack was correctly set during the pipeline run, in addition to checking the post-run conditions.

Consider enhancing the test to verify that the active stack is correctly set during the pipeline run. This could involve querying the active stack within the pipeline execution context and asserting that it matches the expected stack.


def test_pipeline_run_with_different_stack(clean_client: "Client"):
"""Tests that the run command works with a different stack."""
runner = CliRunner()
Expand Down
Loading