forked from fastapi/typer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Support for common pydantic types
Fixes fastapi#181
- Loading branch information
Showing
21 changed files
with
501 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
Pydantic types such as [AnyUrl](https://docs.pydantic.dev/latest/api/networks/#pydantic.networks.AnyUrl) or [EmailStr](https://docs.pydantic.dev/latest/api/networks/#pydantic.networks.EmailStr) can be very convenient to describe and validate some parameters. | ||
|
||
You can add pydantic from typer's optional dependencies | ||
|
||
<div class="termy"> | ||
|
||
```console | ||
// Pydantic comes with typer[all] | ||
$ pip install "typer[all]" | ||
---> 100% | ||
Successfully installed typer rich pydantic | ||
|
||
// Alternatively, you can install Pydantic independently | ||
$ pip install pydantic | ||
---> 100% | ||
Successfully installed pydantic | ||
``` | ||
|
||
</div> | ||
|
||
|
||
You can then use them as parameter types. | ||
|
||
=== "Python 3.6+ Argument" | ||
|
||
```Python hl_lines="5" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial001_an.py!} | ||
``` | ||
|
||
=== "Python 3.6+ Argument non-Annotated" | ||
|
||
!!! tip | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="4" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial001.py!} | ||
``` | ||
|
||
=== "Python 3.6+ Option" | ||
|
||
```Python hl_lines="5" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial002_an.py!} | ||
``` | ||
|
||
=== "Python 3.6+ Option non-Annotated" | ||
|
||
!!! tip | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="4" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial002.py!} | ||
``` | ||
|
||
These types are also supported in lists or tuples | ||
|
||
=== "Python 3.6+ list" | ||
|
||
```Python hl_lines="5" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial003_an.py!} | ||
``` | ||
|
||
=== "Python 3.6+ list non-Annotated" | ||
|
||
!!! tip | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="4" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial003.py!} | ||
``` | ||
|
||
=== "Python 3.6+ tuple" | ||
|
||
```Python hl_lines="5" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial004_an.py!} | ||
``` | ||
|
||
=== "Python 3.6+ tuple non-Annotated" | ||
|
||
!!! tip | ||
Prefer to use the `Annotated` version if possible. | ||
|
||
```Python hl_lines="4" | ||
{!> ../docs_src/parameter_types/pydantic_types/tutorial004.py!} | ||
``` |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import typer | ||
from pydantic import EmailStr | ||
|
||
def main(email_arg: EmailStr): | ||
typer.echo(f"email_arg: {email_arg}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import typer | ||
from typing_extensions import Annotated | ||
from pydantic import EmailStr | ||
|
||
def main(email_arg: Annotated[EmailStr, typer.Argument()]): | ||
typer.echo(f"email_arg: {email_arg}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import typer | ||
from pydantic import EmailStr | ||
|
||
def main(email_opt: EmailStr=typer.Option("[email protected]")): | ||
typer.echo(f"email_opt: {email_opt}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import typer | ||
from typing_extensions import Annotated | ||
from pydantic import EmailStr | ||
|
||
def main(email_opt: Annotated[EmailStr, typer.Option()]="[email protected]"): | ||
typer.echo(f"email_opt: {email_opt}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import typer | ||
from pydantic import AnyHttpUrl | ||
|
||
def main(urls: list[AnyHttpUrl] = typer.Option([],"--url")): | ||
typer.echo(f"urls: {urls}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import typer | ||
from typing import List | ||
from typing_extensions import Annotated | ||
from pydantic import AnyHttpUrl | ||
|
||
def main(urls: Annotated[List[AnyHttpUrl], typer.Option("--url", default_factory=list)]): | ||
typer.echo(f"urls: {urls}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import typer | ||
from pydantic import EmailStr, AnyHttpUrl | ||
|
||
def main(user: tuple[str, int, EmailStr, AnyHttpUrl]=typer.Option(..., help="User name, age, email and social media URL")): | ||
name, age, email, url = user | ||
typer.echo(f"name: {name}") | ||
typer.echo(f"age: {age}") | ||
typer.echo(f"email: {email}") | ||
typer.echo(f"url: {url}") | ||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import typer | ||
from typing import Tuple | ||
from typing_extensions import Annotated | ||
from pydantic import EmailStr, AnyHttpUrl | ||
|
||
def main(user: Annotated[Tuple[str, int, EmailStr, AnyHttpUrl], typer.Option(help="User name, age, email and social media URL")]): | ||
name, age, email, url = user | ||
typer.echo(f"name: {name}") | ||
typer.echo(f"age: {age}") | ||
typer.echo(f"email: {email}") | ||
typer.echo(f"url: {url}") | ||
|
||
|
||
if __name__ == "__main__": | ||
typer.run(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import subprocess | ||
import sys | ||
|
||
import typer | ||
from typer.testing import CliRunner | ||
|
||
from docs_src.parameter_types.pydantic_types import tutorial001 as mod | ||
|
||
runner = CliRunner() | ||
|
||
app = typer.Typer() | ||
app.command()(mod.main) | ||
|
||
|
||
def test_help(): | ||
result = runner.invoke(app, ["--help"]) | ||
assert result.exit_code == 0 | ||
|
||
def test_email_arg(): | ||
result = runner.invoke(app, ["[email protected]"]) | ||
assert result.exit_code == 0 | ||
assert "email_arg: [email protected]" in result.output | ||
|
||
def test_email_arg_invalid(): | ||
result = runner.invoke(app, ["invalid"]) | ||
assert result.exit_code != 0 | ||
assert "value is not a valid email address" in result.output | ||
|
||
def test_script(): | ||
result = subprocess.run( | ||
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
encoding="utf-8", | ||
) | ||
assert "Usage" in result.stdout |
36 changes: 36 additions & 0 deletions
36
tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001_an.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import subprocess | ||
import sys | ||
|
||
import typer | ||
from typer.testing import CliRunner | ||
|
||
from docs_src.parameter_types.pydantic_types import tutorial001_an as mod | ||
|
||
runner = CliRunner() | ||
|
||
app = typer.Typer() | ||
app.command()(mod.main) | ||
|
||
|
||
def test_help(): | ||
result = runner.invoke(app, ["--help"]) | ||
assert result.exit_code == 0 | ||
|
||
def test_email_arg(): | ||
result = runner.invoke(app, ["[email protected]"]) | ||
assert result.exit_code == 0 | ||
assert "email_arg: [email protected]" in result.output | ||
|
||
def test_email_arg_invalid(): | ||
result = runner.invoke(app, ["invalid"]) | ||
assert result.exit_code != 0 | ||
assert "value is not a valid email address" in result.output | ||
|
||
def test_script(): | ||
result = subprocess.run( | ||
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
encoding="utf-8", | ||
) | ||
assert "Usage" in result.stdout |
36 changes: 36 additions & 0 deletions
36
tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import subprocess | ||
import sys | ||
|
||
import typer | ||
from typer.testing import CliRunner | ||
|
||
from docs_src.parameter_types.pydantic_types import tutorial002 as mod | ||
|
||
runner = CliRunner() | ||
|
||
app = typer.Typer() | ||
app.command()(mod.main) | ||
|
||
|
||
def test_help(): | ||
result = runner.invoke(app, ["--help"]) | ||
assert result.exit_code == 0 | ||
|
||
def test_email_opt(): | ||
result = runner.invoke(app, ["--email-opt","[email protected]"]) | ||
assert result.exit_code == 0 | ||
assert "email_opt: [email protected]" in result.output | ||
|
||
def test_email_opt_invalid(): | ||
result = runner.invoke(app, ["--email-opt", "invalid"]) | ||
assert result.exit_code != 0 | ||
assert "value is not a valid email address" in result.output | ||
|
||
def test_script(): | ||
result = subprocess.run( | ||
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
encoding="utf-8", | ||
) | ||
assert "Usage" in result.stdout |
36 changes: 36 additions & 0 deletions
36
tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002_an.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import subprocess | ||
import sys | ||
|
||
import typer | ||
from typer.testing import CliRunner | ||
|
||
from docs_src.parameter_types.pydantic_types import tutorial002_an as mod | ||
|
||
runner = CliRunner() | ||
|
||
app = typer.Typer() | ||
app.command()(mod.main) | ||
|
||
|
||
def test_help(): | ||
result = runner.invoke(app, ["--help"]) | ||
assert result.exit_code == 0 | ||
|
||
def test_email_opt(): | ||
result = runner.invoke(app, ["--email-opt","[email protected]"]) | ||
assert result.exit_code == 0 | ||
assert "email_opt: [email protected]" in result.output | ||
|
||
def test_email_opt_invalid(): | ||
result = runner.invoke(app, ["--email-opt", "invalid"]) | ||
assert result.exit_code != 0 | ||
assert "value is not a valid email address" in result.output | ||
|
||
def test_script(): | ||
result = subprocess.run( | ||
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
encoding="utf-8", | ||
) | ||
assert "Usage" in result.stdout |
37 changes: 37 additions & 0 deletions
37
tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial003.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import subprocess | ||
import sys | ||
|
||
import typer | ||
from typer.testing import CliRunner | ||
|
||
from docs_src.parameter_types.pydantic_types import tutorial003 as mod | ||
|
||
runner = CliRunner() | ||
|
||
app = typer.Typer() | ||
app.command()(mod.main) | ||
|
||
|
||
def test_help(): | ||
result = runner.invoke(app, ["--help"]) | ||
assert result.exit_code == 0 | ||
|
||
def test_url_list(): | ||
result = runner.invoke(app, ["--url", "https://example.com", "--url" ,"https://example.org"]) | ||
assert result.exit_code == 0 | ||
assert "https://example.com" in result.output | ||
assert "https://example.org" in result.output | ||
|
||
def test_url_invalid(): | ||
result = runner.invoke(app, ["--url", "invalid", "--url" ,"https://example.org"]) | ||
assert result.exit_code != 0 | ||
assert "Input should be a valid URL" in result.output | ||
|
||
def test_script(): | ||
result = subprocess.run( | ||
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
encoding="utf-8", | ||
) | ||
assert "Usage" in result.stdout |
Oops, something went wrong.