unlimited argument for an option with comma spliter
Alirezaaraby opened this issue · 2 comments
First Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the Typer documentation, with the integrated search.
- I already searched in Google "How to X in Typer" and didn't find any information.
- I already read and followed all the tutorial in the docs and didn't find an answer.
- I already checked if it is not related to Typer but to Click.
Commit to Help
- I commit to help with one of those options 👆
Example Code
import typer
def main(command: List[str] = typer.Option(None)):
print(command)
Description
I want to pass unlimited multiple arguments to type.option
with comma splitter like below.
$ python cli.py add test -C "hi I'm test", "hello this is test"
I want to get a list like ["hi I'm test","hello this is test"]
from the above input.
Operating System
Windows
Operating System Details
Windows Version 10.0.19045.2486
Typer Version
0.7.0
Python Version
Python 3.9.1
Additional Context
No response
As far as i understand the intended way to use a list type parameter would be like this:
$ python app.py --command arg1 --command arg2
['arg1', 'arg2']
If you really want to use comma separated strings you could do the following:
from typing import Annotated
import typer
def comma_list(raw: str) -> list[str]:
return raw.split(",")
def main(
command: Annotated[list, typer.Option(parser=comma_list)],
):
print(command)
if __name__ == "__main__":
typer.run(main)
$ python potato/main.py --command "hello","world"
['hello', 'world']
Note that using list[str]
instead of list
for the command
parameter seems to attempt some type conversion magic resulting in a nested list so this isn't perfect. Personally I would just keep it simple and do something like this instead:
import typer
def main(commands: str = typer.Option()):
cmd_list = commands.split(",")
print(cmd_list)
if __name__ == "__main__":
typer.run(main)
I implemented something quite similar in my cli
where it takes multiple values as part of an argument in a standard unix fashion i.e separated by spaces.
Essentially extending on what @heiskane is suggesting you do for Option
you can define an argument as follows:
from typing import Optional, List
from typing_extensions import Annotated
import typer
@app.command("ack")
async def acknowledge(
ids: Annotated[List[int], typer.Argument(help="alarm id")], #multiple ids
message: Annotated[
Optional[str],
typer.Option(
"-m",
"--message",
help="comment to add to history",
),
] = None,
):
for id in ids:
print(id)
See issue on my project for more detail.