-
-
Notifications
You must be signed in to change notification settings - Fork 682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
โจ Support for pydantic options #803
base: master
Are you sure you want to change the base?
Conversation
๐ Docs preview for commit bfa4e6d at: https://c0ad6c82.typertiangolo.pages.dev |
๐ Docs preview for commit a6a7004 at: https://efd73f25.typertiangolo.pages.dev |
๐ Docs preview for commit 3e37bb5 at: https://f4caeab2.typertiangolo.pages.dev |
๐ Docs preview for commit 6c76ab9 at: https://cc7a8711.typertiangolo.pages.dev |
๐ Docs preview for commit ebb5877 at: https://6cfbeacd.typertiangolo.pages.dev |
๐ Docs preview for commit 12be77e at: https://ab20f60a.typertiangolo.pages.dev |
ProblemIf we want to allow sequences of pydantic models, things get unreadable quite fast. Let's look at an example of a nested pydantic model with a sequence of another model: from typing import Optional, List
import typer
import pydantic
class Pet(pydantic.BaseModel):
name: str
species: str
class Person(pydantic.BaseModel):
name: str
age: Optional[float] = None
pets: List[Pet]
def main(person: Person):
print(person, type(person))
if __name__ == "__main__":
typer.run(main) The script could be called like this: $ python pets.py --person.name Jeff --person.pets.name Lassie --person.pets.species dog If we want to add multiple pets, we can just supply $ python pets.py --person.name Jeff --person.pets.name Lassie --person.pets.species dog --person.pets.name Nala --person.pets.species cat We don't explicitly state which pet names and species belong together and have to rely on the correct order of parameters. In my opinion this is potentially confusing for the CLI user and may lead to bugs. Potential SolutionTo make the mapping more explicit, we could allow to enable Indexed lists could be implemented independently of this PR and should work for all lists.
from typing import List
import typer
def main(indexed_list: List[int] = typer.Option(..., indexed=True)):
print(indexed_list)
if __name__ == "__main__":
typer.run(main) This would then produce the following help text: $ python indexed_list.py --help
Usage: indexed_list.py [OPTIONS]
โญโ Options โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ * --indexed-list[n] INTEGER [default: None] [required] โ
โ --help Show this message and โ
โ exit. โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ And could be used like this: $ python indexed_list.py --indexed-list[1] 0 --indexed-list[0] 1 --indexed-list[2] 2
[1, 0, 2] Note how the order of the input parameters doesn't matter anymore because the indices are given explicitly. Notes on ImplementationImplementing this might not be trivial, but I think it could be possible by forwarding unknown options as described in the Edit: This might actually be easier using token normalization. Do you have any opinions on this? |
@pypae why limiting the pydantic models to
My current use case requires a set of commands with a
I'm not sure how many users would required deep nested commands in their CLI, and if that's the case using a |
I started working on a standalone package to support this functionality, so you can use It's still WIP, and for now only covers the same basic behavior as this PR. |
๐ Summary
This PR adds support for pydantic options as requested in the following issue: #111
In particular it implements the behavior I described in #111 (comment).
The implementation changes the signature of the callback to add all fields of the (possibly nested)
pydantic
models of the original callback astyper.Option
s. As a result the implementation is largely independent oftyper
and could also be used as a standalone package which could be activated with an additional decorator on the command functions:Usage as a decorator (draft)
๐ Related PRs
โ๏ธ To Do
typer.Option
andtyper.Argument
insidepydantic
modelspydantic
modelsAllow sequences of pydantic models.I suggest implementing indexed list options first, see the comment below.