Pydantic
Suppose you want to use pydantic to manage your validation logic instead of Cyclopts.
Pydantic offers a validate_call()
decorator that performs validation checks on invocation.
from cyclopts import App
from pydantic import validate_call, PositiveInt
app = App()
@app.command
@validate_call
def foo(value: PositiveInt):
print(value)
app()
$ python my-script.py foo 10
10
$ python my-script.py foo -1
╭─ Error ────────────────────────────────────────────────────────────╮
│ 1 validation error for foo │
│ 0 │
│ Input should be greater than 0 [type=greater_than, │
│ input_value=-1, input_type=int] │
│ For further information visit │
│ https://errors.pydantic.dev/2.5/v/greater_than │
╰────────────────────────────────────────────────────────────────────╯
A benefit of this approach is that calling your decorated function from python code will still perform these validation checks.
Pydantic's types are aliases for Annotated[python_type, additional_metadata]
, so they are naturally compatible with Cyclopts.