diff --git a/docs/tutorial/parameter-types/pydantic-types.md b/docs/tutorial/parameter-types/pydantic-types.md index d2762b0e3e..8a97903a58 100644 --- a/docs/tutorial/parameter-types/pydantic-types.md +++ b/docs/tutorial/parameter-types/pydantic-types.md @@ -14,6 +14,11 @@ Successfully installed typer rich pydantic $ pip install pydantic ---> 100% Successfully installed pydantic + +// Or if you want to use EmailStr +$ pip install "pydantic[email]" +---> 100% +Successfully installed pydantic, email-validator ``` diff --git a/docs_src/parameter_types/pydantic_types/tutorial001.py b/docs_src/parameter_types/pydantic_types/tutorial001.py index 4aec54161a..219aa7d788 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial001.py +++ b/docs_src/parameter_types/pydantic_types/tutorial001.py @@ -1,9 +1,9 @@ import typer -from pydantic import EmailStr +from pydantic import AnyHttpUrl -def main(email_arg: EmailStr): - typer.echo(f"email_arg: {email_arg}") +def main(url_arg: AnyHttpUrl): + typer.echo(f"url_arg: {url_arg}") if __name__ == "__main__": diff --git a/docs_src/parameter_types/pydantic_types/tutorial001_an.py b/docs_src/parameter_types/pydantic_types/tutorial001_an.py index c92dbce546..b67db5b39a 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial001_an.py +++ b/docs_src/parameter_types/pydantic_types/tutorial001_an.py @@ -1,10 +1,10 @@ import typer -from pydantic import EmailStr +from pydantic import AnyHttpUrl from typing_extensions import Annotated -def main(email_arg: Annotated[EmailStr, typer.Argument()]): - typer.echo(f"email_arg: {email_arg}") +def main(url_arg: Annotated[AnyHttpUrl, typer.Argument()]): + typer.echo(f"url_arg: {url_arg}") if __name__ == "__main__": diff --git a/docs_src/parameter_types/pydantic_types/tutorial002.py b/docs_src/parameter_types/pydantic_types/tutorial002.py index 14ef540743..55491e43d7 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial002.py +++ b/docs_src/parameter_types/pydantic_types/tutorial002.py @@ -1,9 +1,9 @@ import typer -from pydantic import EmailStr +from pydantic import AnyHttpUrl -def main(email_opt: EmailStr = typer.Option("tiangolo@gmail.com")): - typer.echo(f"email_opt: {email_opt}") +def main(url_opt: AnyHttpUrl = typer.Option("https://typer.tiangolo.com")): + typer.echo(f"url_opt: {url_opt}") if __name__ == "__main__": diff --git a/docs_src/parameter_types/pydantic_types/tutorial002_an.py b/docs_src/parameter_types/pydantic_types/tutorial002_an.py index bcf7cf5e15..3b31083dd6 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial002_an.py +++ b/docs_src/parameter_types/pydantic_types/tutorial002_an.py @@ -1,10 +1,10 @@ import typer -from pydantic import EmailStr +from pydantic import AnyHttpUrl from typing_extensions import Annotated -def main(email_opt: Annotated[EmailStr, typer.Option()] = "tiangolo@gmail.com"): - typer.echo(f"email_opt: {email_opt}") +def main(url_opt: Annotated[AnyHttpUrl, typer.Option()] = "tiangolo@gmail.com"): + typer.echo(f"url_opt: {url_opt}") if __name__ == "__main__": diff --git a/docs_src/parameter_types/pydantic_types/tutorial004.py b/docs_src/parameter_types/pydantic_types/tutorial004.py index 66b7b71a25..0d1a889338 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial004.py +++ b/docs_src/parameter_types/pydantic_types/tutorial004.py @@ -1,18 +1,17 @@ from typing import Tuple import typer -from pydantic import AnyHttpUrl, EmailStr +from pydantic import AnyHttpUrl, IPvAnyAddress def main( - user: Tuple[str, int, EmailStr, AnyHttpUrl] = typer.Option( - ..., help="User name, age, email and social media URL" + server: Tuple[str, IPvAnyAddress, AnyHttpUrl] = typer.Option( + ..., help="Server name, IP address and public URL" ), ): - name, age, email, url = user + name, address, url = server typer.echo(f"name: {name}") - typer.echo(f"age: {age}") - typer.echo(f"email: {email}") + typer.echo(f"address: {address}") typer.echo(f"url: {url}") diff --git a/docs_src/parameter_types/pydantic_types/tutorial004_an.py b/docs_src/parameter_types/pydantic_types/tutorial004_an.py index 9fa0ee5494..db24158c76 100644 --- a/docs_src/parameter_types/pydantic_types/tutorial004_an.py +++ b/docs_src/parameter_types/pydantic_types/tutorial004_an.py @@ -1,20 +1,19 @@ from typing import Tuple import typer -from pydantic import AnyHttpUrl, EmailStr +from pydantic import AnyHttpUrl, IPvAnyAddress from typing_extensions import Annotated def main( - user: Annotated[ - Tuple[str, int, EmailStr, AnyHttpUrl], + server: Annotated[ + Tuple[str, IPvAnyAddress, AnyHttpUrl], typer.Option(help="User name, age, email and social media URL"), ], ): - name, age, email, url = user + name, address, url = server typer.echo(f"name: {name}") - typer.echo(f"age: {age}") - typer.echo(f"email: {email}") + typer.echo(f"address: {address}") typer.echo(f"url: {url}") diff --git a/pyproject.toml b/pyproject.toml index fe63356032..5dff7e946e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ homepage = "https://github.com/tiangolo/typer" standard = [ "shellingham >=1.3.0", "rich >=10.11.0", - "pydantic[email] >=2.0.0", + "pydantic >=2.0.0", ] [tool.pdm] diff --git a/requirements-tests.txt b/requirements-tests.txt index f1e0d8955b..4ca60799c8 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -10,4 +10,4 @@ ruff ==0.2.0 # Needed explicitly by typer-slim rich >=10.11.0 shellingham >=1.3.0 -pydantic[email] >=2.0.0 +pydantic >=2.0.0 diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001.py index e8d226088b..6802abd41b 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001.py @@ -17,16 +17,16 @@ def test_help(): assert result.exit_code == 0 -def test_email_arg(): - result = runner.invoke(app, ["tiangolo@gmail.com"]) +def test_url_arg(): + result = runner.invoke(app, ["https://typer.tiangolo.com"]) assert result.exit_code == 0 - assert "email_arg: tiangolo@gmail.com" in result.output + assert "url_arg: https://typer.tiangolo.com" in result.output -def test_email_arg_invalid(): +def test_url_arg_invalid(): result = runner.invoke(app, ["invalid"]) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "Input should be a valid URL" in result.output def test_script(): diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001_an.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001_an.py index 167c1ce3a8..ab6d6213ab 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001_an.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial001_an.py @@ -17,16 +17,16 @@ def test_help(): assert result.exit_code == 0 -def test_email_arg(): - result = runner.invoke(app, ["tiangolo@gmail.com"]) +def test_url_arg(): + result = runner.invoke(app, ["https://typer.tiangolo.com"]) assert result.exit_code == 0 - assert "email_arg: tiangolo@gmail.com" in result.output + assert "url_arg: https://typer.tiangolo.com" in result.output -def test_email_arg_invalid(): +def test_url_arg_invalid(): result = runner.invoke(app, ["invalid"]) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "Input should be a valid URL" in result.output def test_script(): diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002.py index 265e1d3191..54d33208d2 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002.py @@ -17,16 +17,16 @@ def test_help(): assert result.exit_code == 0 -def test_email_opt(): - result = runner.invoke(app, ["--email-opt", "tiangolo@gmail.com"]) +def test_url_opt(): + result = runner.invoke(app, ["--url-opt", "https://typer.tiangolo.com"]) assert result.exit_code == 0 - assert "email_opt: tiangolo@gmail.com" in result.output + assert "url_opt: https://typer.tiangolo.com" in result.output -def test_email_opt_invalid(): - result = runner.invoke(app, ["--email-opt", "invalid"]) +def test_url_opt_invalid(): + result = runner.invoke(app, ["--url-opt", "invalid"]) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "Input should be a valid URL" in result.output def test_script(): diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002_an.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002_an.py index 1d0475d009..6c9c598fdd 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002_an.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial002_an.py @@ -17,16 +17,16 @@ def test_help(): assert result.exit_code == 0 -def test_email_opt(): - result = runner.invoke(app, ["--email-opt", "tiangolo@gmail.com"]) +def test_url_opt(): + result = runner.invoke(app, ["--url-opt", "https://typer.tiangolo.com"]) assert result.exit_code == 0 - assert "email_opt: tiangolo@gmail.com" in result.output + assert "url_opt: https://typer.tiangolo.com" in result.output -def test_email_opt_invalid(): - result = runner.invoke(app, ["--email-opt", "invalid"]) +def test_url_opt_invalid(): + result = runner.invoke(app, ["--url-opt", "invalid"]) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "Input should be a valid URL" in result.output def test_script(): diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004.py index e51c2b5b89..5fa549b0cb 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004.py @@ -18,22 +18,25 @@ def test_help(): def test_tuple(): - result = runner.invoke( - app, ["--user", "Camila", "23", "camila@example.org", "https://example.com"] - ) + result = runner.invoke(app, ["--server", "Example", "::1", "https://example.com"]) assert result.exit_code == 0 - assert "name: Camila" in result.output - assert "age: 23" in result.output - assert "email: camila@example.org" in result.output + assert "name: Example" in result.output + assert "address: ::1" in result.output assert "url: https://example.com" in result.output -def test_tuple_invalid(): +def test_tuple_invalid_ip(): result = runner.invoke( - app, ["--user", "Camila", "23", "invalid", "https://example.com"] + app, ["--server", "Invalid", "invalid", "https://example.com"] ) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "value is not a valid IPv4 or IPv6 address" in result.output + + +def test_tuple_invalid_url(): + result = runner.invoke(app, ["--server", "Invalid", "::1", "invalid"]) + assert result.exit_code != 0 + assert "Input should be a valid URL" in result.output def test_script(): diff --git a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004_an.py b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004_an.py index dde6671976..7849a3e2ae 100644 --- a/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004_an.py +++ b/tests/test_tutorial/test_parameter_types/test_pydantic_types/test_tutorial004_an.py @@ -18,22 +18,25 @@ def test_help(): def test_tuple(): - result = runner.invoke( - app, ["--user", "Camila", "23", "camila@example.org", "https://example.com"] - ) + result = runner.invoke(app, ["--server", "Example", "::1", "https://example.com"]) assert result.exit_code == 0 - assert "name: Camila" in result.output - assert "age: 23" in result.output - assert "email: camila@example.org" in result.output + assert "name: Example" in result.output + assert "address: ::1" in result.output assert "url: https://example.com" in result.output -def test_tuple_invalid(): +def test_tuple_invalid_ip(): result = runner.invoke( - app, ["--user", "Camila", "23", "invalid", "https://example.com"] + app, ["--server", "Invalid", "invalid", "https://example.com"] ) assert result.exit_code != 0 - assert "value is not a valid email address" in result.output + assert "value is not a valid IPv4 or IPv6 address" in result.output + + +def test_tuple_invalid_url(): + result = runner.invoke(app, ["--server", "Invalid", "::1", "invalid"]) + assert result.exit_code != 0 + assert "Input should be a valid URL" in result.output def test_script():