lablup / lablup/backend.ai

Accept and honor `--output` on the v2 CLI as well

Open
#13,431 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
670
Forks
183
Avg merge
15h 13m
Merged PRs (30d)
368

Description

### Main idea

`--output` should work on the v2 CLI the same way it works on v1, but v2 cannot honor it today: it has no console renderer, so the flag would have exactly one truthful value.

```console
$ backend.ai service list --output=json # v1, works after #13370
$ backend.ai v2 domain list --output=json # Error: No such option: --output
$ backend.ai --output=json v2 domain list # parses, then is ignored — JSON either way
```

Raised in review of #13370: the v2 CLI is just `backend.ai` with `v2` prefixed, so it should behave identically. That is correct — it is the same CLI, and "works on v1, errors on v2" is not explainable to a user.

### Why it was not simply included in #13370

`--output` becomes behaviour through `set_client_config()` → `get_output_handler()` (`src/ai/backend/client/cli/extensions.py:15-36`), reached via `pass_ctx_obj`. v2 uses neither: `grep -c pass_ctx_obj src/ai/backend/client/cli/v2/` is **0**. v2 commands call `print_result()`, which unconditionally serialises to JSON:

```python
# src/ai/backend/client/cli/v2/helpers.py:214-221
def print_result(data: Any) -> None:
"""Print a Pydantic model or dict as formatted JSON."""
...
sys.stdout.write(json_str + "\n")
```

So injecting the option into v2 as-is would parse `--output=console` and discard it — the flag would advertise a mode that does not exist. #13370 explicitly rejected advertising `--output` where it is not honored, and this would reintroduce that.

### Why this is contained, not a 362-command change

There is a **single choke point**. There are 362 v2 leaf command registrations and **338 `print_result()` call sites**. Giving that one function a console mode covers essentially the whole v2 tree.

| Step | Where |
|---|---|
| Add a console rendering path to `print_result()` | `src/ai/backend/client/cli/v2/helpers.py:214` |
| Resolve the mode (root-level `--output`, or the command-level one) | same file; v2 has no `CLIContext`, so decide whether to read `CliContextInfo` directly or adopt the output framework |
| Attach `--output` to v2 commands | needs a v2 equivalent of `pass_ctx_obj`'s attachment point, or an explicit shared decorator |
| Audit the commands that do not call `print_result()` | `grep -rL print_result src/ai/backend/client/cli/v2 --include='*.py'` — 56 modules |

### Open question

Whether v2 should grow its own console renderer, or route through the existing output framework (`ctx.output.print_item` / `print_list`) that v1 uses. The second gives one renderer for both trees and is what #1925 is converging v1 toward; the first is less work now and less coupling. Worth deciding before writing code, since it determines whether `print_result` survives at all.

### Anything else?

Related: #13370 (`--output` accepted on v1 subcommands), #1925 (consistent use of the output framework).

Contributor guide

Open the contributing guide

Research direction

Start with print_result() in src/ai/backend/client/cli/v2/helpers.py and inspect how v2 commands register options, then compare the existing v1 output framework. Decide whether v2 should share that renderer or add a console path, and audit the 56 modules that do not call print_result(). Done means --output is accepted and honored consistently across v2 commands without advertising an unsupported mode.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, developer-experience
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.