Skip to content

Commit d2e59f7

Browse files
committed
baris review
1 parent 1933cb5 commit d2e59f7

File tree

5 files changed

+75
-24
lines changed

5 files changed

+75
-24
lines changed

src/zenml/cli/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,45 @@
225225
This syntax can also be combined to create more complex filters using the `or`
226226
and `and` keywords.
227227
228+
Output formats
229+
--------------
230+
231+
All ``list`` commands support multiple output formats, making it easy to
232+
pipe ZenML CLI output into scripts, CI/CD pipelines, or analysis tools.
233+
234+
Use the ``--output`` (or ``-o``) option to specify the format:
235+
236+
```bash
237+
# Get stack data as JSON for processing with jq
238+
zenml stack list --output=json | jq '.items[] | select(.name=="production")'
239+
240+
# Export pipeline runs to CSV for analysis
241+
zenml pipeline runs list --output=csv > pipeline_runs.csv
242+
243+
# Get deployment info as YAML for configuration management
244+
zenml deployment list --output=yaml
245+
246+
# Filter columns to see only what you need
247+
zenml stack list --columns=id,name,orchestrator
248+
249+
# Combine filtering with custom output formats
250+
zenml pipeline list --columns=id,name --output=json
251+
```
252+
253+
Available formats:
254+
255+
- **json** - Structured data with pagination info, ideal for programmatic use
256+
- **yaml** - Human-readable structured format, great for configuration
257+
- **csv** - Comma-separated values for spreadsheets and data analysis
258+
- **tsv** - Tab-separated values for simpler parsing
259+
- **table** (default) - Formatted tables with colors and alignment
260+
261+
You can also control the default output format and table width using
262+
environment variables:
263+
264+
- ``ZENML_DEFAULT_OUTPUT`` - Set the default output format (e.g., ``json``)
265+
- ``ZENML_CLI_COLUMN_WIDTH`` - Override terminal width for consistent formatting
266+
228267
Artifact Stores
229268
---------------
230269

src/zenml/cli/model.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ def model() -> None:
8686
"id",
8787
"name",
8888
"latest_version_name",
89-
"description",
9089
"tags",
91-
"use_cases",
9290
],
9391
)
9492
def list_models(

src/zenml/cli/pipeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ def builds() -> None:
898898

899899

900900
@builds.command("list", help="List all pipeline builds.")
901-
@list_options(PipelineBuildFilter, default_columns=["id", "name"])
901+
@list_options(PipelineBuildFilter, default_columns=["id"])
902902
def list_pipeline_builds(
903903
columns: str, output_format: OutputFormat, **kwargs: Any
904904
) -> None:

src/zenml/cli/project.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ def project() -> None:
3737

3838

3939
@project.command("list")
40-
@list_options(
41-
ProjectFilter, default_columns=["active", "id", "name", "description"]
42-
)
40+
@list_options(ProjectFilter, default_columns=["active", "id", "name"])
4341
@click.pass_context
4442
def list_projects(
4543
ctx: click.Context,

src/zenml/cli/utils.py

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,24 @@ def _component_display_name(
19461946
return name.replace("_", " ")
19471947

19481948

1949+
def _active_status(
1950+
is_active: bool, output_format: OutputFormat
1951+
) -> Union[str, bool]:
1952+
"""Format active status based on output format.
1953+
1954+
Args:
1955+
is_active: Whether the item is active.
1956+
output_format: The output format.
1957+
1958+
Returns:
1959+
For table format: green dot if active, empty string if not.
1960+
For other formats: boolean value.
1961+
"""
1962+
if output_format == "table":
1963+
return "[green]●[/green]" if is_active else ""
1964+
return is_active
1965+
1966+
19491967
def get_execution_status_emoji(status: "ExecutionStatus") -> str:
19501968
"""Returns an emoji representing the given execution status.
19511969
@@ -2148,14 +2166,15 @@ def generate_stack_row(
21482166
is_active = active_id is not None and stack.id == active_id
21492167

21502168
row: Dict[str, Any] = {
2151-
"active": "[green]●[/green]"
2152-
if is_active and output_format == "table"
2153-
else ("Yes" if is_active else ""),
2169+
"active": _active_status(is_active, output_format),
21542170
}
21552171

21562172
for component_type in StackComponentType:
21572173
components = stack.components.get(component_type)
2158-
header = component_type.value.upper().replace("_", " ")
2174+
if output_format == "table":
2175+
header = component_type.value.upper().replace("_", " ")
2176+
else:
2177+
header = component_type.value
21592178
row[header] = components[0].name if components else "-"
21602179

21612180
return row
@@ -2179,9 +2198,7 @@ def generate_project_row(
21792198
is_active = active_id is not None and project.id == active_id
21802199

21812200
return {
2182-
"active": "[green]●[/green]"
2183-
if is_active and output_format == "table"
2184-
else ("Yes" if is_active else ""),
2201+
"active": _active_status(is_active, output_format),
21852202
}
21862203

21872204

@@ -2203,9 +2220,7 @@ def generate_user_row(
22032220
is_active = active_id is not None and user.id == active_id
22042221

22052222
return {
2206-
"active": "[green]●[/green]"
2207-
if is_active and output_format == "table"
2208-
else ("Yes" if is_active else ""),
2223+
"active": _active_status(is_active, output_format),
22092224
}
22102225

22112226

@@ -2257,9 +2272,7 @@ def generate_component_row(
22572272
is_active = active_id is not None and component.id == active_id
22582273

22592274
return {
2260-
"active": "[green]●[/green]"
2261-
if is_active and output_format == "table"
2262-
else ("Yes" if is_active else ""),
2275+
"active": _active_status(is_active, output_format),
22632276
"name": component.name,
22642277
"component_id": component.id,
22652278
"flavor": component.flavor_name,
@@ -2282,15 +2295,15 @@ def generate_connector_row(
22822295
Returns:
22832296
Dict with connector data for display.
22842297
"""
2285-
is_active = active_connector_ids and connector.id in active_connector_ids
2298+
is_active = bool(
2299+
active_connector_ids and connector.id in active_connector_ids
2300+
)
22862301
labels = [f"{label}:{value}" for label, value in connector.labels.items()]
22872302
resource_name = connector.resource_id or "<multiple>"
22882303
resource_types_str = "\n".join(connector.emojified_resource_types)
22892304

22902305
return {
2291-
"active": "[green]●[/green]"
2292-
if is_active and output_format == "table"
2293-
else ("Yes" if is_active else ""),
2306+
"active": _active_status(is_active, output_format),
22942307
"name": connector.name,
22952308
"id": connector.id,
22962309
"type": connector.emojified_connector_type,
@@ -2868,8 +2881,11 @@ def is_sorted_or_filtered(ctx: click.Context) -> bool:
28682881
Returns:
28692882
True if any parameter source differs from default, else False.
28702883
"""
2884+
display_options = {"output_format", "columns"}
28712885
try:
2872-
for _, source in ctx._parameter_source.items():
2886+
for param, source in ctx._parameter_source.items():
2887+
if param in display_options:
2888+
continue
28732889
if source != click.core.ParameterSource.DEFAULT:
28742890
return True
28752891
return False

0 commit comments

Comments
 (0)