Skip to main content

A typed wrapper around argparse using pydantic models

Project description

pydantic-argparse-extensible

A typed wrapper for argparse leveraging pydantic to generate command line interfaces.

The pydantic_argparse_extensible provides an ArgModel class, which inherits from pydantic.BaseModel and provides a few new methods. For simple arguments, there's not much you need to do:

from pydantic import ConfigDict
from pydantic_argparse_extensible import ArgModel

class Args(ArgModel):
    model_config = ConfigDict(use_attribute_docstrings=True)

    user: str
    """The username to connect to."""

    host: str
    """The host to connect to."""

def main() -> None:
    args = Args.argparse()
    print(args)


if __name__ == "__main__":
    main()


# $ python -m example_simple --help
# usage: example_simple.py [-h] --user USER --host HOST
# 
# options:
#   -h, --help   show this help message and exit
#   --user USER  The username to connect to.
#   --host HOST  The host to connect to.

Then, pydantic helps ensure that all the data from argparse is typed as you expect. Plus, we get autocompletion for argument fields on the Args class, as well as hover documentation that matches the CLI --help output.

You can use ArgModels as reusable sets of arguments. Here, Args will include arguments defined on both of the models it includes:

class CommonArgs(ArgModel):
    pass

class GitHubArgs(ArgModel):
    pass

class Args(ArgModel):
    common: CommonArgs
    github: GitHubArgs

The power of pydantic_argparse_extensible lies in letting you opt out of its automatic generation logic in order to manually create more complex command-line interfaces that aren't supported by typer and other alternatives:

class Address(BaseModel):
    user: str
    host: str

class Ec2Instance(BaseModel):
    address: Address
    instance_id: str

class Args(ArgModel):
    deploy: bool
    system_profile: Path = Path("/nix/var/nix/profiles/system")
    aws_role_arn: str | None = None
    ec2_instances: list[Ec2Instance]

    @classmethod
    def update_argparser(cls, parser: ArgumentParser, manual: set[str] | None = None) -> None:
        parser.add_argument(
            "--no-deploy",
            action="store_false",
            dest="deploy",
            help="Don't deploy the resulting builds.",
        )

        # This argument doesn't appear as a field at all, but it's used to help
        # define the `ec2_instances` field.
        parser.add_argument(
            "--ssh-user",
            help="Username to use when connecting to `--ec2-instance` hosts via SSH.",
        )

        parser.add_argument(
            "--ec2-instance",
            nargs=2,
            metavar=("HOST_NAME", "INSTANCE_ID"),
            dest="ec2_instances",
            help="AWS EC2 instances to deploy to, if any.",
        )

        # We defined arguments for the `deploy` and `ec2_instances` fields
        # manually, so we tell `pydantic_argparse_extensible` to skip them when
        # generating the CLI.
        super().update_argparser(parser, manual={"deploy", "ec2_instances"})

    @classmethod
    def from_parsed_args(cls, args: Namespace, partial: dict[str, Any] | None = None) -> Self:
        ec2_instances = []
        ssh_user = args.ssh_user
        if args.ec2_instances:
            ec2_instances = [
                Ec2Instance(address=Address(user=ssh_user, host=host), instance_id=instance_id)
                for (host, instance_id) in args.ec2_instances
            ]

        # We parsed the value for the `ec2_instances` field manually, so we
        # tell `pydantic_argparse_extensible` to ignore the `ec2_instances`
        # attribute on the `args` when constructing the model.
        partial = {"ec2_instances": ec2_instances}
        return super().from_parsed_args(args, partial)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_argparse_extensible-1.3.6.tar.gz (4.2 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file pydantic_argparse_extensible-1.3.6.tar.gz.

File metadata

File hashes

Hashes for pydantic_argparse_extensible-1.3.6.tar.gz
Algorithm Hash digest
SHA256 0cb136785ae87c20dc10fae7e60fe6665c4d89d5574e152e99657ebbecb2bce2
MD5 5fb02a60dab0e819f251349f3be87c0f
BLAKE2b-256 9508305a2b97e3b1ae2d5870c2bddbe00874dc635f6fbde9a4207fff24d2f31a

See more details on using hashes here.

File details

Details for the file pydantic_argparse_extensible-1.3.6-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_argparse_extensible-1.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 5e757df1793c44599d56b51ed834d15ccdcc9e4e79c71e6c7e65ae5a7571ab26
MD5 7ca7c412400a192b2cbe90cb9e659906
BLAKE2b-256 4369a49d131f2393d26c2dcfa9328e61042a6f8984565bed0e53318a029bf7ea

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page