A lightweight Python library for creating wrapper functions with enhanced argument handling using sentinel values to mark parameters as required or optional.
Project description
Welcome to func_args Documentation
Overview
func_args is a lightweight Python library for creating wrapper functions with enhanced argument handling. It solves common problems when working with third-party APIs that have suboptimal interface designs.
The library provides sentinel values (REQ and OPT) that can be used as function parameter defaults to:
Mark parameters as required
Mark parameters as optional and easily exclude them from kwargs
Additionally, func_args includes dataclasses enhancements for parameter validation and conversion.
Design Philosophy
func_args follows these core principles:
Explicit over implicit - Parameters are clearly marked as required or optional
Fail fast - Required parameters are validated early
Minimal overhead - Simple API with minimal processing cost
Flexible integration - Works with any Python function without modifying the original
Type hint support - Full support for Python type annotations
Consistent error handling - Clear error messages for missing required parameters
The library solves several common problems:
Creating wrapper functions around third-party APIs with poor parameter interfaces
Building flexible functions with many optional parameters
Enforcing required parameters without complex conditional logic
Removing optional parameters from kwargs dictionaries to avoid passing unused parameters
Usage Examples
Basic Sentinels
In this example, we create a wrapper around an AWS S3 put_object API:
def put_object(
Bucket: str,
Key: str,
Body: bytes,
Metadata: T.Optional[dict[str, str]] = ...,
Tags: T.Optional[dict[str, str]] = ...,
):
...
from func_args.api import REQ, OPT, prepare_kwargs
# Our enhanced wrapper with REQ and OPT
def better_put_object(
Bucket: str = REQ,
Key: str = REQ,
Body: bytes = REQ,
Metadata: T.Optional[dict[str, str]] = OPT,
Tags: T.Optional[dict[str, str]] = OPT,
):
# custom parameter handling
if Metadata is NA:
Metadata = {"creator": "admin"}
if Tags is NA:
Tags = {"creator": "admin"}
# Prepare kwargs with validation
kwargs = dict(
Bucket=Bucket,
Key=Key,
Body=Body,
Metadata=Metadata,
Tags=Tags,
)
# This will:
# 1. Raise ParamError if any REQ values remain
# 2. Remove any OPT values
# 3. Return a clean dict with only provided values
cleaned_kwargs = prepare_kwargs(kwargs)
# Call the original API with only the necessary parameters
return put_object(**cleaned_kwargs)
Required Parameter Validation
from func_args.arg import REQ, check_required
# Function with required parameters
def create_user(username=REQ, email=REQ, role="user"):
# Validate required parameters
check_required(username=username, email=email)
# If we got here, all required parameters were provided
return {"username": username, "email": email, "role": role}
# This works
user = create_user(username="alice", email="alice@example.com")
# This raises ParamError: "Missing required argument: 'email'"
try:
user = create_user(username="bob")
except ParamError as e:
print(e)
Optional Parameter Removal
from func_args.arg import OPT, remove_optional
# Function with many optional parameters
def search_items(query, limit=10, offset=0, sort_by=OPT, filter_by=OPT, include_deleted=False):
# Build base query parameters
params = {
"query": query,
"limit": limit,
"offset": offset,
"sort_by": sort_by,
"filter_by": filter_by,
"include_deleted": include_deleted,
}
# Remove optional parameters that weren't provided
clean_params = remove_optional(**params)
# Now we can safely pass to the API without sending None values or defaults
return api_search(**clean_params)
Enhanced Dataclasses
import dataclasses
from func_args.dataclass import BaseModel, REQ, OPT
@dataclasses.dataclass
class UserParameters(BaseModel):
"""Parameter class for user operations with validation."""
# Required fields
username: str = dataclasses.field(default=REQ)
email: str = dataclasses.field(default=REQ)
# Optional fields
display_name: str = dataclasses.field(default=OPT)
role: str = dataclasses.field(default="user")
tags: list = dataclasses.field(default_factory=list)
def validate_email(self):
"""Additional validation logic."""
if not "@" in self.email:
raise ValueError("Invalid email format")
def __post_init__(self):
# Call the base class validation
super().__post_init__()
# Perform additional validation
self.validate_email()
# Usage
params = UserParameters(username="alice", email="alice@example.com")
# Convert to dict with all fields (including OPT sentinel values)
full_dict = params.to_dict()
# {"username": "alice", "email": "alice@example.com", "display_name": OPT, "role": "user", "tags": []}
# Convert to dict with only provided values (excluding OPT sentinels)
kwargs = params.to_kwargs()
# {"username": "alice", "email": "alice@example.com", "role": "user", "tags": []}
Install
func_args is released on PyPI, so all you need is to:
$ pip install func-args
To upgrade to latest version:
$ pip install --upgrade func-args
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 func_args-1.0.1.tar.gz.
File metadata
- Download URL: func_args-1.0.1.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f07c2620fa446da54eb0888d5063167b1068d566e1f9a1879fe912c3d7497821
|
|
| MD5 |
d6fb4ee61953133fc2fab398cfcb4e1e
|
|
| BLAKE2b-256 |
c9f0e3410fc39cb3b4d64206cb97c42a7ff1c2e4cd26516903069daf19b2102b
|
File details
Details for the file func_args-1.0.1-py3-none-any.whl.
File metadata
- Download URL: func_args-1.0.1-py3-none-any.whl
- Upload date:
- Size: 15.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4562f4eaa0d68142a6ab5ad1f212959fabc2c4cc029b77446bcc377d737e3db4
|
|
| MD5 |
19ee414fccc0a65d360fba2bf172832d
|
|
| BLAKE2b-256 |
8f0451cce2f0ebe02fc7f15186658a9f129fba2d3b5055e3764d1bf087839988
|