fastapi / typer

Typer, build great CLIs. Easy to code. Based on Python type hints.
https://typer.tiangolo.com/
MIT License
15.37k stars 655 forks source link

Support for bytes in Options and Arguments #536

Open AlexanderPodorov opened 1 year ago

AlexanderPodorov commented 1 year ago

First Check

Commit to Help

Example Code

import typer

def main(name: bytes):
    typer.echo(name)

if  __name__ == '__main__':
    typer.run(main)

Description

It would be nice if we could add support for bytes in order to use it in contexts where bytes are expected (e.g. base64 encode/decode, password hashing, etc.)

Wanted Solution

Support for bytes type. Currently typer says: RuntimeError: Type not yet supported: <class 'bytes'>

Wanted Code

import typer

def main(name: bytes):
    typer.echo(name)

if  __name__ == '__main__':
    typer.run(main)

Alternatives

Always use encode/decode methods.

Operating System

macOS

Operating System Details

No response

Typer Version

0.7.0

Python Version

3.11.1

Additional Context

No response

marcosschroh commented 1 year ago

Hi,

is there any news on this issue?

ESPR3SS0 commented 4 months ago

Hello, I could look into adding this!

However just so you know, custom types can be made easily. A type for bytes could be made like:

import typer
from typing_extensions import Annotated
app = typer.Typer()
class Bytes(self, value):
    def __init__(self, value):
        self.value = value.encode()
def parse_bytes(val):
    return Bytes(val).value

def func(input: Annotated[Bytes, typer.Argument(parser=parse_bytes)]):
    ....
    ....
    return

The greatest hassle with this solution is remembering to add `parser=parse_bytes' to all the Bytes arguments. So, could be worth natively supporting it.

JPHutchins commented 1 month ago

This would also be useful for my use cases (firmware / transport protocols). Though, instead of supporting "bytes" directly, wouldn't we need to support "encodings"?

For example, a type specified as:

It seems to me that the only arg that would make sense for simply "bytes" would be python byte literals, with all their downsides.

Would be good to scope this to common encodings since there are thousands.