Pydantic types

Pydantic types such as AnyUrl or EmailStr can be very convenient to describe and validate some parameters.

Pydantic is installed automatically when installing Typer with its extra standard dependencies:

// Pydantic comes with typer
$ pip install typer
---> 100%
Successfully installed typer rich shellingham pydantic

// Alternatively, you can install Pydantic independently
$ pip install pydantic
---> 100%
Successfully installed pydantic

// Or if you want to use EmailStr
$ pip install "pydantic[email]"
---> 100%
Successfully installed pydantic, email-validator

You can then use them as parameter types.

from typing import Annotated

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(url_arg: Annotated[AnyHttpUrl, typer.Argument()]):
    typer.echo(f"url_arg: {url_arg}")


if __name__ == "__main__":
    app()
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(url_arg: AnyHttpUrl):
    typer.echo(f"url_arg: {url_arg}")


if __name__ == "__main__":
    app()
from typing import Annotated

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(url_opt: Annotated[AnyHttpUrl, typer.Option()] = "https://typer.tiangolo.com"):
    typer.echo(f"url_opt: {url_opt}")


if __name__ == "__main__":
    app()
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(url_opt: AnyHttpUrl = typer.Option("https://typer.tiangolo.com")):
    typer.echo(f"url_opt: {url_opt}")


if __name__ == "__main__":
    app()

These types are also supported in lists or tuples:

from typing import Annotated

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(
    urls: Annotated[list[AnyHttpUrl], typer.Option("--url", default_factory=list)],
):
    typer.echo(f"urls: {urls}")


if __name__ == "__main__":
    app()
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

import typer
from pydantic import AnyHttpUrl

app = typer.Typer()


@app.command()
def main(urls: list[AnyHttpUrl] = typer.Option([], "--url")):
    typer.echo(f"urls: {urls}")


if __name__ == "__main__":
    app()
from typing import Annotated

import typer
from pydantic import AnyHttpUrl, IPvAnyAddress

app = typer.Typer()


@app.command()
def main(
    server: Annotated[
        tuple[str, IPvAnyAddress, AnyHttpUrl],
        typer.Option(help="User name, age, email and social media URL"),
    ],
):
    name, address, url = server
    typer.echo(f"name: {name}")
    typer.echo(f"address: {address}")
    typer.echo(f"url: {url}")


if __name__ == "__main__":
    app()
🤓 Other versions and variants

Tip

Prefer to use the Annotated version if possible.

import typer
from pydantic import AnyHttpUrl, IPvAnyAddress

app = typer.Typer()


@app.command()
def main(
    server: tuple[str, IPvAnyAddress, AnyHttpUrl] = typer.Option(
        ..., help="Server name, IP address and public URL"
    ),
):
    name, address, url = server
    typer.echo(f"name: {name}")
    typer.echo(f"address: {address}")
    typer.echo(f"url: {url}")


if __name__ == "__main__":
    app()