Safe, non-error-raising, alternative to Pydantic validate_call decorator
Project description
validate-call-safe
validate_call_safe
is a safe, non-error-raising alternative to Pydantic's validate_call
decorator.
It allows you to validate function arguments while gracefully handling validation errors through an error model,
inspired by effects handlers, returning them as structured data models instead of raising exceptions.
This therefore means that side effects ('erroring') are transformed into return types.
The return type annotation of a decorated function is modified accordingly as the Union
of the
existing return type with the provided error model type.
Features
- Validates function arguments using Pydantic's existing
validate_call
decorator - Returns a custom error model instead of raising exceptions when validation fails
- Configurable error information, including JSON representation and string representation of errors
- Written for Pydantic v2 (more specifically at version 2.8.2)
Installation
pip install validate-call-safe
Usage
Basic Usage
Here we use an example model with all error fields: you may only want one of error_json
,
error_str
and error_repr
.
from pydantic import BaseModel, Json
from validate_call_safe import validate_call_safe
class CustomErrorModel(BaseModel):
error_type: str
error_json: Json
error_str: str
error_repr: str
@validate_call_safe(CustomErrorModel)
def int_noop(a: int) -> int:
return a
success = int_noop(a=1) # 1
failure = int_noop(a="A") # CustomErrorModel(error_type='ValidationError', ...)
See the examples directory for a standalone program.
Comparison with validate_call
With validate_call_safe
you don't have to catch the expected ValidationError
from Pydantic's validate_call
:
# Using validate_call
from pydantic import validate_call
@validate_call
def unsafe_int_noop(a: int) -> int:
return a
try:
unsafe_int_noop(a="A")
except ValidationError as e:
print(f"Error: {e}")
# Using validate_call_safe
from validate_call_safe import validate_call_safe
@validate_call_safe(CustomErrorModel)
def safe_int_noop(a: int) -> int:
return a
result = safe_int_noop(a="A")
match result:
case CustomErrorModel():
print(f"Error: {result.error_type}")
case int():
... # Regular business logic here
Ideas
- Complete with reference to original (and maybe just rely on original, seems the more reliably correct way?)
- Restrict to ValidationError
- Specify non-ValidationError exceptions to capture
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
Built Distribution
File details
Details for the file validate_call_safe-0.1.0.tar.gz
.
File metadata
- Download URL: validate_call_safe-0.1.0.tar.gz
- Upload date:
- Size: 2.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.18.1 CPython/3.10.14 Linux/5.15.0-117-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0cab577e303074f55a5bcf8d563b2dcb70fd13698d79b1cdc05a4139e190754f |
|
MD5 | a692a0fecc02bb1e261ef36ed13f90b8 |
|
BLAKE2b-256 | 4f00232ac9d2ba3eb949ece744f74cabda9ad118d4fa2dc432957e46280d796d |
File details
Details for the file validate_call_safe-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: validate_call_safe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.18.1 CPython/3.10.14 Linux/5.15.0-117-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ed961e56ae70b26c50667bf8712c1f0c6db107103db7a199ac6275231053454b |
|
MD5 | 5bde724dac09e6bbbd07e1cccb988531 |
|
BLAKE2b-256 | 1191ab315b994c2458c045e999defaf278f5e1a428340a6be5435a0ae0ee4de2 |