Stack Components
zenml.cli.stack_components
Functionality to generate stack component CLI commands.
generate_stack_component_copy_command(component_type)
Generates a copy
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_copy_command(
component_type: StackComponentType,
) -> Callable[[str, str], None]:
"""Generates a `copy` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument("source_component_name_or_id", type=str, required=True)
@click.argument("target_component", type=str, required=True)
def copy_stack_component_command(
source_component_name_or_id: str,
target_component: str,
) -> None:
"""Copies a stack component.
Args:
source_component_name_or_id: Name or id prefix of the
component to copy.
target_component: Name of the copied component.
"""
track_event(AnalyticsEvent.COPIED_STACK_COMPONENT)
with console.status(
f"Copying {display_name} " f"`{source_component_name_or_id}`..\n"
):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Fetch the stack component
client = Client()
existing_component = (
cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=source_component_name_or_id,
)
)
# Register a new one with a new name
component_create_model = ComponentModel(
user=client.active_user.id,
project=client.active_project.id,
name=target_component,
flavor=existing_component.flavor,
configuration=existing_component.configuration,
type=existing_component.type,
)
client.register_stack_component(component=component_create_model)
return copy_stack_component_command
generate_stack_component_delete_command(component_type)
Generates a delete
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_delete_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `delete` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument("name_or_id", type=str)
def delete_stack_component_command(name_or_id: str) -> None:
"""Deletes a stack component.
Args:
name_or_id: The name of the stack component to delete.
"""
with console.status(f"Deleting {display_name} '{name_or_id}'...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Fetch the existing stack component
client = Client()
existing_comp = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
# Delete the component
client.deregister_stack_component(existing_comp)
cli_utils.declare(f"Deleted {display_name}: {name_or_id}")
return delete_stack_component_command
generate_stack_component_describe_command(component_type)
Generates a describe
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_describe_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `describe` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
@click.argument(
"name_or_id",
type=str,
required=False,
)
def describe_stack_component_command(name_or_id: str) -> None:
"""Prints details about the active/specified component.
Args:
name_or_id: Name or id of the component to describe.
"""
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
active_component = client.active_stack_model.components.get(
component_type, []
)
if name_or_id:
try:
component = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
except KeyError as e:
cli_utils.error(str(e)) # noqa
else:
if len(active_component) == 0:
cli_utils.error(
f"Cannot describe any {component_type} since the active "
f"stack has no {component_type} and no name or id was "
f"provided."
)
component = active_component[0]
is_active = (
len(active_component) > 0 and component.id == active_component[0].id
)
cli_utils.print_stack_component_configuration(
component=component.to_hydrated_model(), active_status=is_active
)
return describe_stack_component_command
generate_stack_component_down_command(component_type)
Generates a down
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, bool], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_down_command(
component_type: StackComponentType,
) -> Callable[[str, bool], None]:
"""Generates a `down` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
@click.argument("name_or_id", type=str, required=False)
@click.option(
"--force",
"-f",
"force",
is_flag=True,
help="Deprovisions local resources instead of suspending them.",
)
@click.option(
"--yes",
"-y",
"old_force",
is_flag=True,
help="DEPRECATED: Deprovisions local resources instead of suspending "
"them. Use `-f/--force` instead.",
)
def down_stack_component_command(
name_or_id: str,
force: bool = False,
old_force: bool = False,
) -> None:
"""Stops/Tears down the local deployment of a stack component.
Args:
name_or_id: The name or id of the component to stop/deprovision.
force: Deprovision local resources instead of suspending them.
old_force: DEPRECATED: Deprovision local resources instead of
suspending them. Use `-f/--force` instead.
"""
if old_force:
force = old_force
cli_utils.warning(
"The `--yes` flag will soon be deprecated. Use `--force` "
"or `-f` instead."
)
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
try:
component_model = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
except KeyError as e:
cli_utils.error(str(e)) # noqa
return
from zenml.stack import StackComponent
component = StackComponent.from_model(component_model=component_model)
display_name = _component_display_name(component_type)
if not force:
if not component.is_suspended:
cli_utils.declare(
f"Suspending local resources for {display_name} "
f"'{component.name}'."
)
try:
component.suspend()
except NotImplementedError:
cli_utils.error(
f"Provisioning local resources not implemented for "
f"{display_name} '{component.name}'. If you want to "
f"deprovision all resources for this component, use "
f"the `--force/-f` flag."
)
else:
cli_utils.declare(
f"No running resources found for {display_name} "
f"'{component.name}'."
)
else:
if component.is_provisioned:
cli_utils.declare(
f"Deprovisioning resources for {display_name} "
f"'{component.name}'."
)
component.deprovision()
else:
cli_utils.declare(
f"No provisioned resources found for {display_name} "
f"'{component.name}'."
)
return down_stack_component_command
generate_stack_component_explain_command(component_type)
Generates an explain
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_explain_command(
component_type: StackComponentType,
) -> Callable[[], None]:
"""Generates an `explain` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
def explain_stack_components_command() -> None:
"""Explains the concept of the stack component."""
component_module = import_module(f"zenml.{component_type.plural}")
if component_module.__doc__ is not None:
md = Markdown(component_module.__doc__)
console.print(md)
else:
console.print(
"The explain subcommand is yet not available for "
"this stack component. For more information, you can "
"visit our docs page: https://docs.zenml.io/ and "
"stay tuned for future releases."
)
return explain_stack_components_command
generate_stack_component_flavor_delete_command(component_type)
Generates a delete
command for a single flavor of a component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_flavor_delete_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `delete` command for a single flavor of a component.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name",
type=str,
required=True,
)
def delete_stack_component_flavor_command(name: str) -> None:
"""Deletes a flavor.
Args:
name: The name of the flavor.
"""
with console.status(f"Deleting a {display_name} flavor: {name}`...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Fetch the flavor
client = Client()
existing_flavor = client.get_flavor_by_name_and_type(
name=name, component_type=component_type
)
# Delete the flavor
client.delete_flavor(existing_flavor)
cli_utils.declare(
f"Successfully deleted flavor '{existing_flavor.name}' "
f"for stack component '{existing_flavor.type}'."
)
return delete_stack_component_flavor_command
generate_stack_component_flavor_describe_command(component_type)
Generates a describe
command for a single flavor of a component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_flavor_describe_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `describe` command for a single flavor of a component.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name",
type=str,
required=True,
)
def describe_stack_component_flavor_command(name: str) -> None:
"""Describes a flavor based on its config schema.
Args:
name: The name of the flavor.
"""
with console.status(f"Describing {display_name} flavor: {name}`...\n"):
# Fetch the existing flavor
client = Client()
flavor_model = client.get_flavor_by_name_and_type(
name=name, component_type=component_type
)
cli_utils.describe_pydantic_object(flavor_model.config_schema)
return describe_stack_component_flavor_command
generate_stack_component_flavor_list_command(component_type)
Generates a list
command for the flavors of a stack component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_flavor_list_command(
component_type: StackComponentType,
) -> Callable[[], None]:
"""Generates a `list` command for the flavors of a stack component.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
def list_stack_component_flavor_command() -> None:
"""Lists the flavors for a single type of stack component."""
with console.status(f"Listing {display_name} flavors`...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Fetch the flavors
client = Client()
flavors = client.get_flavors_by_type(component_type=component_type)
# Print the flavors
cli_utils.print_flavor_list(flavors=flavors)
return list_stack_component_flavor_command
generate_stack_component_flavor_register_command(component_type)
Generates a register
command for the flavors of a stack component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_flavor_register_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `register` command for the flavors of a stack component.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"source",
type=str,
required=True,
)
def register_stack_component_flavor_command(source: str) -> None:
"""Adds a flavor for a stack component type.
Args:
source: The source file to read the flavor from.
"""
with console.status(f"Registering a new {display_name} flavor`...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
# Create a new model
# TODO: Investigate how we can create this model without empty
# strings as values for name and config_schema
flavor_create_model = FlavorModel(
source=source,
type=component_type,
user=client.active_user.id,
project=client.active_project.id,
name="",
config_schema="",
)
# Register the new model
new_flavor = client.create_flavor(flavor_create_model)
cli_utils.declare(
f"Successfully registered new flavor '{new_flavor.name}' "
f"for stack component '{new_flavor.type}'."
)
return register_stack_component_flavor_command
generate_stack_component_get_command(component_type)
Generates a get
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_get_command(
component_type: StackComponentType,
) -> Callable[[], None]:
"""Generates a `get` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
def get_stack_component_command() -> None:
"""Prints the name of the active component."""
cli_utils.print_active_config()
cli_utils.print_active_stack()
active_stack = Client().active_stack_model
components = active_stack.components.get(component_type, None)
display_name = _component_display_name(component_type)
if components:
cli_utils.declare(f"Active {display_name}: '{components[0].name}'")
else:
cli_utils.warning(
f"No {display_name} set for active stack "
f"('{active_stack.name}')."
)
return get_stack_component_command
generate_stack_component_list_command(component_type)
Generates a list
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_list_command(
component_type: StackComponentType,
) -> Callable[[], None]:
"""Generates a `list` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
def list_stack_components_command() -> None:
"""Prints a table of stack components."""
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
components = client.list_stack_components_by_type(type=component_type)
hydrated_comps = [s.to_hydrated_model() for s in components]
cli_utils.print_components_table(
client=client,
component_type=component_type,
components=hydrated_comps,
)
return list_stack_components_command
generate_stack_component_logs_command(component_type)
Generates a logs
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, bool], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_logs_command(
component_type: StackComponentType,
) -> Callable[[str, bool], None]:
"""Generates a `logs` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
@click.argument("name_or_id", type=str, required=False)
@click.option(
"--follow",
"-f",
is_flag=True,
help="Follow the log file instead of just displaying the current logs.",
)
def stack_component_logs_command(
name_or_id: str, follow: bool = False
) -> None:
"""Displays stack component logs.
Args:
name_or_id: The name of the stack component to display logs for.
follow: Follow the log file instead of just displaying the current
logs.
"""
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
try:
component_model = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
except KeyError as e:
cli_utils.error(str(e)) # noqa
else:
from zenml.stack import StackComponent
component = StackComponent.from_model(
component_model=component_model
)
display_name = _component_display_name(component_type)
log_file = component.log_file
if not log_file or not fileio.exists(log_file):
cli_utils.warning(
f"Unable to find log file for {display_name} "
f"'{component.name}'."
)
return
if follow:
try:
with open(log_file, "r") as f:
# seek to the end of the file
f.seek(0, 2)
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
line = line.rstrip("\n")
click.echo(line)
except KeyboardInterrupt:
cli_utils.declare(f"Stopped following {display_name} logs.")
else:
with open(log_file, "r") as f:
click.echo(f.read())
return stack_component_logs_command
generate_stack_component_register_command(component_type)
Generates a register
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, str, bool, List[str]], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_register_command(
component_type: StackComponentType,
) -> Callable[[str, str, bool, List[str]], None]:
"""Generates a `register` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name",
type=str,
)
@click.option(
"--flavor",
"-f",
"flavor",
help=f"The flavor of the {display_name} to register.",
required=True,
type=str,
)
@click.option(
"--share",
"share",
is_flag=True,
help="Use this flag to share this stack component with other users.",
type=click.BOOL,
)
@click.argument("args", nargs=-1, type=click.UNPROCESSED)
def register_stack_component_command(
name: str,
flavor: str,
share: bool,
args: List[str],
) -> None:
"""Registers a stack component.
Args:
name: Name of the component to register.
flavor: Flavor of the component to register.
share: Share the stack with other users.
args: Additional arguments to pass to the component.
"""
# Parse the given args
# name is guaranteed to be set by parse_name_and_extra_arguments
name, parsed_args = cli_utils.parse_name_and_extra_arguments( # type: ignore[assignment]
list(args) + [name], expand_args=True
)
with console.status(f"Registering {display_name} '{name}'...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
# click<8.0.0 gives flags a default of None
if share is None:
share = False
# Create a new stack component model
component_create_model = ComponentModel(
user=client.active_user.id,
project=client.active_project.id,
is_shared=share,
name=name,
flavor=flavor,
configuration=parsed_args,
type=component_type,
)
# Register the new model
client = Client()
client.register_stack_component(component_create_model)
cli_utils.declare(
f"Successfully registered {display_name} `{name}`."
)
return register_stack_component_command
generate_stack_component_remove_attribute_command(component_type)
Generates remove_attribute
command for a specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, List[str]], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_remove_attribute_command(
component_type: StackComponentType,
) -> Callable[[str, List[str]], None]:
"""Generates `remove_attribute` command for a specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name_or_id",
type=str,
required=True,
)
@click.argument("args", nargs=-1, type=click.UNPROCESSED)
def remove_attribute_stack_component_command(
name_or_id: str, args: List[str]
) -> None:
"""Removes one or more attributes from a stack component.
Args:
name_or_id: The name of the stack component to remove the
attribute from.
args: Additional arguments to pass to the remove_attribute command.
"""
with console.status(f"Updating {display_name} '{name_or_id}'...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Parse the given args
parsed_args = cli_utils.parse_unknown_component_attributes(args)
# Fetch the existing component
client = Client()
existing_comp = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
# Remove the specified attributes
for arg in parsed_args:
try:
existing_comp.configuration.pop(arg)
except KeyError:
cli_utils.error(
f"Cannot remove non-existent attribute '{arg}' from "
f"{existing_comp.type} '{existing_comp.name}'"
f"."
)
# Update the stack component
client.update_stack_component(component=existing_comp)
cli_utils.declare(
f"Successfully updated {display_name} `{name_or_id}`."
)
return remove_attribute_stack_component_command
generate_stack_component_rename_command(component_type)
Generates a rename
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_rename_command(
component_type: StackComponentType,
) -> Callable[[str, str], None]:
"""Generates a `rename` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name_or_id",
type=str,
required=True,
)
@click.argument(
"new_name",
type=str,
required=True,
)
def rename_stack_component_command(name_or_id: str, new_name: str) -> None:
"""Rename a stack component.
Args:
name_or_id: The name of the stack component to rename.
new_name: The new name of the stack component.
"""
with console.status(f"Renaming {display_name} '{name_or_id}'...\n"):
cli_utils.print_active_config()
cli_utils.print_active_stack()
# Fetch the existing component
client = Client()
existing_component = (
cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
)
# Rename and update the existing component
client.update_stack_component(
component=existing_component.copy(update={"name": new_name}),
)
cli_utils.declare(
f"Successfully renamed {display_name} `{name_or_id}` to"
f" `{new_name}`."
)
return rename_stack_component_command
generate_stack_component_share_command(component_type)
Generates an share
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_share_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates an `share` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name_or_id",
type=str,
required=False,
)
def share_stack_component_command(
name_or_id: str,
) -> None:
"""Shares a stack component.
Args:
name_or_id: The name or id of the stack component to update.
"""
with console.status(f"Updating {display_name} '{name_or_id}'...\n"):
cli_utils.print_active_config()
# Get the existing component
client = Client()
existing_component = (
cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
)
existing_component.is_shared = True
# Update the component
client.update_stack_component(component=existing_component)
cli_utils.declare(
f"Successfully shared {display_name} " f"`{name_or_id}`."
)
return share_stack_component_command
generate_stack_component_up_command(component_type)
Generates a up
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_up_command(
component_type: StackComponentType,
) -> Callable[[str], None]:
"""Generates a `up` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
@click.argument("name_or_id", type=str, required=False)
def up_stack_component_command(name_or_id: str) -> None:
"""Deploys a stack component locally.
Args:
name_or_id: The name or_id of the stack component to deploy.
"""
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
try:
component_model = cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
except KeyError as e:
cli_utils.error(str(e)) # noqa
return
from zenml.stack import StackComponent
component = StackComponent.from_model(component_model=component_model)
display_name = _component_display_name(component_type)
if component.is_running:
cli_utils.declare(
f"Local deployment is already running for {display_name} "
f"'{component.name}'."
)
return
if not component.is_provisioned:
cli_utils.declare(
f"Provisioning local resources for {display_name} "
f"'{component.name}'."
)
try:
component.provision()
except NotImplementedError:
cli_utils.error(
f"Provisioning local resources not implemented for "
f"{display_name} '{component.name}'."
)
if not component.is_running:
cli_utils.declare(
f"Resuming local resources for {display_name} "
f"'{component.name}'."
)
component.resume()
return up_stack_component_command
generate_stack_component_update_command(component_type)
Generates an update
command for the specific stack component type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
Returns:
Type | Description |
---|---|
Callable[[str, List[str]], NoneType] |
A function that can be used as a |
Source code in zenml/cli/stack_components.py
def generate_stack_component_update_command(
component_type: StackComponentType,
) -> Callable[[str, List[str]], None]:
"""Generates an `update` command for the specific stack component type.
Args:
component_type: Type of the component to generate the command for.
Returns:
A function that can be used as a `click` command.
"""
display_name = _component_display_name(component_type)
@click.argument(
"name_or_id",
type=str,
required=False,
)
@click.argument("args", nargs=-1, type=click.UNPROCESSED)
def update_stack_component_command(
name_or_id: Optional[str], args: List[str]
) -> None:
"""Updates a stack component.
Args:
name_or_id: The name or id of the stack component to update.
args: Additional arguments to pass to the update command.
"""
args = list(args)
if name_or_id:
args.append(name_or_id)
# Parse the given args
name_or_id, parsed_args = cli_utils.parse_name_and_extra_arguments(
args,
expand_args=True,
name_mandatory=False,
)
cli_utils.print_active_config()
cli_utils.print_active_stack()
client = Client()
if not name_or_id:
cli_utils.declare(
f"No name or id was provided. Trying to update the active "
f"{display_name}."
)
active_stack = client.active_stack_model
if component_type not in active_stack.components:
cli_utils.error(
f"The active stack has no {display_name} and no name or id "
f"was provided."
)
name_or_id = str(active_stack.components[component_type][0].id)
with console.status(f"Updating {display_name} '{name_or_id}'...\n"):
# Get the existing component
existing_component = (
cli_utils.get_component_by_id_or_name_or_prefix(
client=client,
component_type=component_type,
id_or_name_or_prefix=name_or_id,
)
)
# Update the existing configuration
updated_attributes = {
**existing_component.configuration,
**parsed_args,
}
# Update the component
client.update_stack_component(
component=existing_component.copy(
update={"configuration": updated_attributes}
)
)
cli_utils.declare(
f"Successfully updated {display_name} `{name_or_id}`."
)
return update_stack_component_command
register_all_stack_component_cli_commands()
Registers CLI commands for all stack components.
Source code in zenml/cli/stack_components.py
def register_all_stack_component_cli_commands() -> None:
"""Registers CLI commands for all stack components."""
for component_type in StackComponentType:
register_single_stack_component_cli_commands(
component_type, parent_group=cli
)
register_single_stack_component_cli_commands(component_type, parent_group)
Registers all basic stack component CLI commands.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_type |
StackComponentType |
Type of the component to generate the command for. |
required |
parent_group |
Group |
The parent group to register the commands to. |
required |
Source code in zenml/cli/stack_components.py
def register_single_stack_component_cli_commands(
component_type: StackComponentType, parent_group: click.Group
) -> None:
"""Registers all basic stack component CLI commands.
Args:
component_type: Type of the component to generate the command for.
parent_group: The parent group to register the commands to.
"""
command_name = component_type.value.replace("_", "-")
singular_display_name = _component_display_name(component_type)
plural_display_name = _component_display_name(component_type, plural=True)
@parent_group.group(
command_name,
cls=TagGroup,
help=f"Commands to interact with {plural_display_name}.",
tag=CliCategories.STACK_COMPONENTS,
)
def command_group() -> None:
"""Group commands for a single stack component type."""
# zenml stack-component get
get_command = generate_stack_component_get_command(component_type)
command_group.command(
"get", help=f"Get the name of the active {singular_display_name}."
)(get_command)
# zenml stack-component describe
describe_command = generate_stack_component_describe_command(component_type)
command_group.command(
"describe",
help=f"Show details about the (active) {singular_display_name}.",
)(describe_command)
# zenml stack-component list
list_command = generate_stack_component_list_command(component_type)
command_group.command(
"list", help=f"List all registered {plural_display_name}."
)(list_command)
# zenml stack-component register
register_command = generate_stack_component_register_command(component_type)
context_settings = {"ignore_unknown_options": True}
command_group.command(
"register",
context_settings=context_settings,
help=f"Register a new {singular_display_name}.",
)(register_command)
# zenml stack-component update
update_command = generate_stack_component_update_command(component_type)
context_settings = {"ignore_unknown_options": True}
command_group.command(
"update",
context_settings=context_settings,
help=f"Update a registered {singular_display_name}.",
)(update_command)
# zenml stack-component share
share_command = generate_stack_component_share_command(component_type)
context_settings = {"ignore_unknown_options": True}
command_group.command(
"share",
context_settings=context_settings,
help=f"Share a registered {singular_display_name}.",
)(share_command)
# zenml stack-component remove-attribute
remove_attribute_command = (
generate_stack_component_remove_attribute_command(component_type)
)
context_settings = {"ignore_unknown_options": True}
command_group.command(
"remove-attribute",
context_settings=context_settings,
help=f"Remove attributes from a registered {singular_display_name}.",
)(remove_attribute_command)
# zenml stack-component rename
rename_command = generate_stack_component_rename_command(component_type)
command_group.command(
"rename", help=f"Rename a registered {singular_display_name}."
)(rename_command)
# zenml stack-component delete
delete_command = generate_stack_component_delete_command(component_type)
command_group.command(
"delete", help=f"Delete a registered {singular_display_name}."
)(delete_command)
# zenml stack-component copy
copy_command = generate_stack_component_copy_command(component_type)
command_group.command(
"copy", help=f"Copy a registered {singular_display_name}."
)(copy_command)
# zenml stack-component up
up_command = generate_stack_component_up_command(component_type)
command_group.command(
"up",
help=f"Provisions or resumes local resources for the "
f"{singular_display_name} if possible.",
)(up_command)
# zenml stack-component down
down_command = generate_stack_component_down_command(component_type)
command_group.command(
"down",
help=f"Suspends resources of the local {singular_display_name} "
f"deployment.",
)(down_command)
# zenml stack-component logs
logs_command = generate_stack_component_logs_command(component_type)
command_group.command(
"logs", help=f"Display {singular_display_name} logs."
)(logs_command)
# zenml stack-component explain
explain_command = generate_stack_component_explain_command(component_type)
command_group.command(
"explain", help=f"Explaining the {plural_display_name}."
)(explain_command)
# zenml stack-component flavor
@command_group.group(
"flavor", help=f"Commands to interact with {plural_display_name}."
)
def flavor_group() -> None:
"""Group commands to handle flavors for a stack component type."""
# zenml stack-component flavor register
register_flavor_command = generate_stack_component_flavor_register_command(
component_type=component_type
)
flavor_group.command(
"register",
help=f"Identify a new flavor for {plural_display_name}.",
)(register_flavor_command)
# zenml stack-component flavor list
list_flavor_command = generate_stack_component_flavor_list_command(
component_type=component_type
)
flavor_group.command(
"list",
help=f"List all registered flavors for {plural_display_name}.",
)(list_flavor_command)
# zenml stack-component flavor describe
describe_flavor_command = generate_stack_component_flavor_describe_command(
component_type=component_type
)
flavor_group.command(
"describe",
help=f"Describe a {singular_display_name} flavor.",
)(describe_flavor_command)
# zenml stack-component flavor delete
delete_flavor_command = generate_stack_component_flavor_delete_command(
component_type=component_type
)
flavor_group.command(
"delete",
help=f"Delete a {plural_display_name} flavor.",
)(delete_flavor_command)