Bytes¶
You can declare bytes for CLI arguments and options.
By default, bytes are created by encoding the input string with UTF-8 (the same as Python's default for str.encode()), but you can configure the encoding and error handling.
Default UTF-8 encoding¶
This example declares a bytes argument using the default UTF-8 encoding:
import typer
def main(data: bytes):
# Default encoding is UTF-8
print(f"Bytes: {data!r}")
if __name__ == "__main__":
typer.run(main)
Try it with non-ASCII characters and you will get UTF-8 encoded bytes.
Custom encoding on Argument¶
You can set a specific encoding for a bytes argument:
import typer
def main(data: bytes = typer.Argument(..., encoding="latin-1")):
# Argument configured to use latin-1
print(f"Bytes (latin-1): {data!r}")
if __name__ == "__main__":
typer.run(main)
Here the argument is configured with encoding="latin-1", so the command line input will be encoded accordingly.
Custom encoding and errors on Option¶
You can also configure a bytes option with a specific encoding and error handling mode:
import typer
def main(token: bytes = typer.Option(..., encoding="ascii", errors="replace")):
# Option configured with ascii encoding and errors=replace
print(f"Token: {token!r}")
if __name__ == "__main__":
typer.run(main)
The errors parameter supports the same values as Python's str.encode() (e.g. "strict", "ignore", "replace").
Primary use case¶
The goal of supporting bytes is to let you write a single function that works both:
- Inside Typer: when called as a CLI, Typer parses command line input and converts it to
bytesusing the configuredencoding/errors. - Outside Typer: when called as regular Python code, you can pass
bytesdirectly, without any CLI parsing involved.
This keeps your function reusable in both contexts while giving you control over how CLI text inputs are converted to bytes.