|
| 1 | +--- |
| 2 | +tags: |
| 3 | +- interface |
| 4 | +--- |
| 5 | + |
| 6 | +## Overview |
| 7 | + |
| 8 | +When code prints things, it actually writes to one of two virtual files: "standard output" or "standard error". |
| 9 | + |
| 10 | +* For a human user, there's usually no difference: Both `stdout` and `stderr` are visible on the terminal. |
| 11 | +* For machines, there's a difference: A script consuming the output of your script "sees" only `stdout`. |
| 12 | + |
| 13 | +Distinguishing between `stdout` and `stderr`, is one of the [Basics recommended by the CLIG](https://clig.dev/#the-basics) |
| 14 | + |
| 15 | +TLDR |
| 16 | + |
| 17 | +* Send output that can be piped and consumed by a next script to `stdout`. |
| 18 | +* Send everything else, especially errors and log messages to `stderr`. |
| 19 | + |
| 20 | +For more explanation, on `stdout` and `stderr`, see also the [Typer Docs](https://typer.tiangolo.com/tutorial/printing/#standard-output-and-standard-error) |
| 21 | + |
| 22 | +## Printing to `stdout` vs `stderr` with Rich |
| 23 | + |
| 24 | +In Rich, you use a `rich.console.Console` object for printing. |
| 25 | + |
| 26 | +* By default, it prints to `stdout`. |
| 27 | +* You can initialize the `Console` with `stderr=True`, so that it prints to `stderr`. |
| 28 | + |
| 29 | +After creating a talk, print: |
| 30 | + |
| 31 | +* the talk ID to `stdout` |
| 32 | +* a logging message to `stderr` |
| 33 | + |
| 34 | +```python |
| 35 | +from rich.console import Console |
| 36 | + |
| 37 | +stdout_console = Console() |
| 38 | +stderr_console = Console(stderr=True) |
| 39 | + |
| 40 | +stdout_console.print(talk.talk_id) |
| 41 | +stderr_console.print("New talk created. 🪅") |
| 42 | +``` |
| 43 | + |
| 44 | +## Testing |
| 45 | + |
| 46 | +For tests with `typer.testing.CliRunner`, it's recommended to verify the content of `stdout` and `stdin` separately. |
| 47 | + |
| 48 | +In order to do that, you need to initialize the `typer.testing.CliRunner` instance with `mix_stderr=False`. |
| 49 | + |
| 50 | +```python |
| 51 | +runner = CliRunner(mix_stderr=False) |
| 52 | +``` |
| 53 | + |
| 54 | +## Iteration vs Keeping the Interface Stable |
| 55 | + |
| 56 | +> Changing output for humans is usually OK. The only way to make an interface easy to use is to iterate on it, and if the output is considered an interface, then you can’t iterate on it. Encourage your users to use --plain or --json in scripts to keep output stable (see Output). |
| 57 | +
|
| 58 | +[CLIG Guidelines / Future-proofing](https://clig.dev/#future-proofing) |
| 59 | + |
| 60 | +## More Info |
| 61 | + |
| 62 | +* [Typer Docs / Printing and Colors / "Standard Output" and "Standard Error"](https://typer.tiangolo.com/tutorial/printing/#standard-output-and-standard-error) |
| 63 | +* [CLIG Guidelines / Basics](https://clig.dev/#the-basics) |
| 64 | +* [CLIG Guidelines / Future-proofing](https://clig.dev/#future-proofing) |
0 commit comments