Metadata-Version: 2.3
Name: argdantic
Version: 1.3.3
Summary: Typed command line interfaces with argparse and pydantic
Author-email: Edoardo Arnaudo <edoardo.arn@gmail.com>
Description-Content-Type: text/markdown
Classifier: Development Status :: 4 - Beta
Classifier: Topic :: Software Development
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Requires-Dist: pydantic >= 2.8.0, < 3.0
Requires-Dist: pydantic-settings >= 2.4.0, < 3
Requires-Dist: python-dotenv >= 1.0.0, < 2.0 ; extra == "all"
Requires-Dist: orjson >= 3.10.0, < 4.0 ; extra == "all"
Requires-Dist: toml >= 0.10.0, < 1.0 ; extra == "all"
Requires-Dist: tomli >= 2.0, < 3.0 ; extra == "all"
Requires-Dist: pyyaml >= 6.0.0, < 7.0 ; extra == "all"
Requires-Dist: tomli-w >= 1.0.0, < 2.0 ; extra == "all"
Requires-Dist: flit >= 3.9.0, < 4.0 ; extra == "dev"
Requires-Dist: ruff >= 0.5.6, < 1.0 ; extra == "dev"
Requires-Dist: mkdocs >= 1.6.0, < 2.0 ; extra == "docs"
Requires-Dist: mkdocs-material >= 9.5.0, < 10.0 ; extra == "docs"
Requires-Dist: mdx-include >= 1.4.0, < 2.0 ; extra == "docs"
Requires-Dist: python-dotenv >= 1.0.0, < 2.0 ; extra == "env"
Requires-Dist: orjson >= 3.10.0, < 4.0 ; extra == "json"
Requires-Dist: coverage >= 7.6.0, < 8.0 ; extra == "test"
Requires-Dist: mock >= 5.1.0, < 6.0 ; extra == "test"
Requires-Dist: pytest >= 8.3.0, < 9.0 ; extra == "test"
Requires-Dist: pytest-cov >= 5.0.0, < 6.0 ; extra == "test"
Requires-Dist: pytest-xdist >= 3.6.0, < 4.0 ; extra == "test"
Requires-Dist: toml >= 0.10.0, < 1.0 ; extra == "toml"
Requires-Dist: tomli >= 2.0, < 3.0 ; extra == "toml"
Requires-Dist: tomli-w >= 1.0.0, < 2.0 ; extra == "toml"
Requires-Dist: pyyaml >= 6.0.0, < 7.0 ; extra == "yaml"
Project-URL: Home, https://github.com/edornd
Provides-Extra: all
Provides-Extra: dev
Provides-Extra: docs
Provides-Extra: env
Provides-Extra: json
Provides-Extra: test
Provides-Extra: toml
Provides-Extra: yaml

# argdantic
Typed command line interfaces with [`argparse`](https://docs.python.org/3/library/argparse.html) and [`pydantic`](https://github.com/pydantic/pydantic).

[![test passing](https://img.shields.io/github/actions/workflow/status/edornd/argdantic/test.yml?branch=main)](https://github.com/edornd/argdantic)
[![coverage](https://img.shields.io/codecov/c/gh/edornd/argdantic)](https://codecov.io/gh/edornd/argdantic)
[![pypi version](https://img.shields.io/pypi/v/argdantic)](https://pypi.org/project/argdantic/)
[![python versions](https://img.shields.io/pypi/pyversions/argdantic)](https://github.com/edornd/argdantic)

[![license](https://img.shields.io/github/license/edornd/argdantic)](https://github.com/edornd/argdantic)
[![documentation](https://img.shields.io/badge/documentation-%F0%9F%93%9A-blue)](https://edornd.github.io/argdantic/)
---

## Features

`argdantic` provides a thin boilerplate layer to provide a modern CLI experience, including:
- **Typed arguments:** arguments require full typing by default, enforcing clarity and help your editor provide better support (linting, hinting).
- **Nested models:** exploit `pydantic` models to scale from simple primitives to complex nested configurations with little effort.
- **Nested commands:** combine commands and build complex hierarchies to build complex interfaces.
- **Validation by default:** thanks to `pydantic`, field validation is provided by default, with the desired complexity.
- **Multiple sources:** arguments can be provided from multiple sources, including environment variables, JSON, TOML and YAML files.

## Quickstart

### Installation
Installing `argdantic` can be done from source, or simply using `pip`.
The only required dependency is, of course, *pydantic*, while the remaining can be selected depending on your needs:

```console
recommended choice: install everything
this includes orjson, pyyaml, tomli, python-dotenv
user@pc:~$ pip install argdantic[all]

env, json, toml or yaml dependencies
user@pc:~$ pip install argdantic[env|json|toml|yaml]

minimum requirement, only pydantic included
user@pc:~$ pip install argdantic
```

### A Simple Example

Creating a CLI with `argdantic` can be as simple as:

```python
from argdantic import ArgParser

# 1. create a CLI instance
parser = ArgParser()


# 2. decorate the function to be called
@parser.command()
def buy(name: str, quantity: int, price: float):
    print(f"Bought {quantity} {name} at ${price:.2f}.")

# 3. Use your CLI by simply calling it
if __name__ == "__main__":
    parser()
```

Then, in a terminal, the `help` command can provide the usual information:

```console
$ python cli.py --help
> usage: buy [-h] --name TEXT --quantity INT --price FLOAT
>
> optional arguments:
>   -h, --help      show this help message and exit
>   --name TEXT
>   --quantity INT
>   --price FLOAT
```

This gives us the required arguments for the execution:

```console
$ python cli.py --name apples --quantity 10 --price 3.4
> Bought 10 apples at $3.40.
```

### Using Models

Plain arguments and `pydantic` models can be mixed together:

```python
from argdantic import ArgParser
from pydantic import BaseModel

parser = ArgParser()


class Item(BaseModel):
    name: str
    price: float


@parser.command()
def buy(item: Item, quantity: int):
    print(f"Bought {quantity} X {item.name} at ${item.price:.2f}.")

if __name__ == "__main__":
    parser()
```

This will produce the following help:

```console
usage: cli.py [-h] --item.name TEXT --item.price FLOAT --quantity INT

optional arguments:
  -h, --help          show this help message and exit
  --item.name TEXT
  --item.price FLOAT
  --quantity INT
```

### Arguments From Different Sources

`argdantic` supports several inputs:
- **`.env` files**, environment variables, and secrets thanks to *pydantic*.
- **JSON files**, using either the standard `json` library, or `orjson` if available.
- **YAML files**, using the `pyyaml` library.
- **TOML files**, using the lightweight `tomli` library.

Sources can be imported and added to each command independently, as such:

```python
from argdantic import ArgParser
from argdantic.sources import EnvSettingsSource, JsonSettingsSource

parser = ArgParser()


@parser.command(
    sources=[
        EnvSettingsSource(env_file=".env", env_file_encoding="utf-8"),
        JsonSettingsSource(path="settings.json"),
    ]
)
def sell(item: str, quantity: int, value: float):
    print(f"Selling: {item} x {quantity}, {value:.2f}$")


if __name__ == "__main__":
    parser()
```

This is just a brief introduction to the library, more examples and details can be found in the [documentation](https://edornd.github.io/argdantic/).

## Contributing

Contributions are welcome! You can open a new issue to report bugs, or suggest new features. If you're brave enough, pull requests are also welcome.

