A clap-inspired declarative CLI argument parser for Python
Project description
clapy-derive
A clap-inspired declarative CLI argument parser for Python.
Define your CLI as a plain class with type annotations — clapy-derive handles parsing, help generation, and type conversion.
from clapy_derive import clapy_arg, clapy_parser
@clapy_parser("version", "verbose")
class Cli:
"""My awesome tool."""
input: str = clapy_arg(short=True, long=True, help="input file")
output: str = clapy_arg(short=True, long=True, default="output.txt")
if __name__ == "__main__":
cli = Cli.parse()
print(cli.input)
print(cli.output)
$ python main.py --input data.csv
data.csv
output.txt
$ python main.py -i data.csv -o result.txt
data.csv
result.txt
$ python main.py --help
usage: cli [-h] [-V] [-v] -i INPUT [-o OUTPUT]
My awesome tool.
options:
-h, --help show this help message and exit
-V, --version show program's version number and exit
-v, --verbose Enable verbose output
-i, --input INPUT input file
-o, --output OUTPUT
Installation
pip install clapy-derive
Usage
Positional arguments
A field with no clapy_arg() becomes a required positional argument — the same as clap's default behaviour for bare struct fields.
@clapy_parser()
class Cli:
name: str # positional, required
greeting: str = "hello" # positional, optional with default
$ python main.py alice
Named flags (--long / -s)
Use clapy_arg(short=True, long=True) to add -x / --xxx flags.
@clapy_parser()
class Cli:
output: str = clapy_arg(short=True, long=True, default="out.txt")
count: int = clapy_arg(short=True, long=True, default=1)
short=True— auto-assign the first character of the field name (-o,-c)long=True— use the field name as the long flag (--output,--count)- Pass an explicit string to override:
short="O",long="out"
Underscores in field names are converted to hyphens on the CLI (output_file → --output-file).
Optional values (T | None)
Annotate with T | None to make an argument optional. The value is None when not provided.
@clapy_parser()
class Cli:
config: str | None = clapy_arg(short=True, long=True)
$ python main.py # cli.config is None
$ python main.py -c x # cli.config == "x"
Multiple values (list[T])
Annotate with list[T] to accept one or more values.
@clapy_parser()
class Cli:
files: list[str] = clapy_arg(short=True, long=True)
$ python main.py --files a.txt b.txt c.txt
Boolean flags
A bool field becomes a store-true flag (default False).
@clapy_parser()
class Cli:
debug: bool = clapy_arg(short=True, long=True)
$ python main.py --debug # cli.debug is True
$ python main.py # cli.debug is False
Built-in flags
Pass strings to @clapy_parser() to enable built-in flags:
| String | Flags added |
|---|---|
"version" |
-V / --version (reads version from package metadata) |
"verbose" |
-v / --verbose (sets cli.verbose: bool) |
@clapy_parser("version", "verbose")
class Cli:
...
Type conversion
clapy-derive infers the conversion type from the field annotation automatically.
| Annotation | CLI input | Python value |
|---|---|---|
str |
"hello" |
"hello" |
int |
"42" |
42 |
float |
"3.14" |
3.14 |
pathlib.Path |
"/tmp/f" |
Path("/tmp/f") |
bool |
flag present | True |
clapy_arg() reference
| Parameter | Type | Default | Description |
|---|---|---|---|
short |
bool | str |
False |
-x flag. True = first char of field name |
long |
bool | str |
True |
--xxx flag. True = field name |
help |
str |
"" |
Help text shown in --help |
default |
Any |
(required) | Default value; makes the argument optional |
choices |
list | None |
None |
Restrict to a set of allowed values |
metavar |
str | None |
None |
Placeholder name in help output |
env |
str | None |
None |
Environment variable to fall back to |
Requirements
- Python 3.12+
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clapy_derive-0.1.0.tar.gz.
File metadata
- Download URL: clapy_derive-0.1.0.tar.gz
- Upload date:
- Size: 5.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e845f63cb84d7996be8d5de1bac8e861a5d84b3161ed41ae76fbeb7ebff5d86
|
|
| MD5 |
84aedfa050f209b9957f59da263dc263
|
|
| BLAKE2b-256 |
0d1ccc0b3efb16ca41d8fe8b3684a9810bdd345dd9a96e6e202fa381af4cae95
|
File details
Details for the file clapy_derive-0.1.0-py3-none-any.whl.
File metadata
- Download URL: clapy_derive-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b9c8512401f0253f1c72daa28ef86b6bf117121078b7d05e9a27556f1231693
|
|
| MD5 |
b2efd1c3bc0c4718386ad6d935c98015
|
|
| BLAKE2b-256 |
75d8f18af4fdbadb6b4866d4c5c0b253940a07575051e87f8389975e3b3767ac
|