Skip to content

fix(cli): keep stdout valid JSON when SDK calls print in --json mode - #547

Open
cdeil wants to merge 1 commit into
roboflow:mainfrom
cdeil:fix-cli-json-stdout
Open

cdeil wants to merge 1 commit into
roboflow:mainfrom
cdeil:fix-cli-json-stdout

Conversation

@cdeil

@cdeil cdeil commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #546.

  • roboflow/cli/_output.py: new context manager sdk_output_to_stderr(args). With --json it redirects stdout to stderr; without --json it does nothing.
  • search --export, image upload <dir>, model upload and version download run their SDK call inside it, so the SDK's progress and status lines move to stderr and stdout carries only the JSON result.
  • model upload now wraps the workspace init in suppress_sdk_output() like the other handlers, which drops "loading Roboflow workspace..." from its output.
  • Text mode (without --json) is unchanged.

Why stderr and not suppress_sdk_output(): for image upload <dir>, the per-image [ERR] lines are currently the only failure signal (#545), so they should stay visible. In JSON mode, stderr already carries the tqdm progress bars.

Test plan

  • tests/cli/test_json_stdout.py: one test per handler with an SDK mock that prints, asserting that stdout parses with json.loads and that the printed line ends up on stderr, plus one test that text mode keeps SDK output on stdout. The four handler tests fail on main and pass with this change.
  • End to end, with HTTP mocked by responses and the commands run through typer.testing.CliRunner: all four commands now print only the JSON document on stdout.
  • Python 3.13: make check_code_quality passes; python -m unittest runs 1214 tests, OK (1 skipped).

search --export, image upload <dir>, model upload and version download
call SDK methods that print progress and status lines to stdout, so
stdout was a mix of plain text and the JSON result. In --json mode these
calls now run with stdout redirected to stderr, where the progress stays
visible. model upload also silences the "loading Roboflow workspace..."
message during workspace init, like the other handlers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--json output is not valid JSON for search --export, image upload <dir>, model upload and version download

1 participant