Skip to main content

A lightweight Python library for creating wrapper functions with enhanced argument handling using sentinel values to mark parameters as required or optional.

Project description

Documentation Status https://github.com/MacHu-GWU/func_args-project/actions/workflows/main.yml/badge.svg https://codecov.io/gh/MacHu-GWU/func_args-project/branch/main/graph/badge.svg https://img.shields.io/pypi/v/func-args.svg https://img.shields.io/pypi/l/func-args.svg https://img.shields.io/pypi/pyversions/func-args.svg https://img.shields.io/badge/✍️_Release_History!--None.svg?style=social&logo=github https://img.shields.io/badge/⭐_Star_me_on_GitHub!--None.svg?style=social&logo=github
https://img.shields.io/badge/Link-API-blue.svg https://img.shields.io/badge/Link-Install-blue.svg https://img.shields.io/badge/Link-GitHub-blue.svg https://img.shields.io/badge/Link-Submit_Issue-blue.svg https://img.shields.io/badge/Link-Request_Feature-blue.svg https://img.shields.io/badge/Link-Download-blue.svg

Welcome to func_args Documentation

https://func-args.readthedocs.io/en/latest/_static/func_args-logo.png

Overview

func_args is a lightweight, zero-dependency Python library that provides sentinel values (REQ and OPT) for enhanced function argument handling. It solves common problems when creating wrapper functions around third-party APIs.

Key features:

  • REQ sentinel — marks parameters as required, with early validation

  • OPT sentinel — marks parameters as optional, automatically excluded from kwargs

  • prepare_kwargs() — validates required and removes optional in one pass

  • BaseModel / BaseFrozenModel — dataclass mixins that bypass the “default after non-default” ordering limitation

Install

$ pip install func-args

Usage

1. Wrapping Third-Party APIs

The most common use case: creating a better interface around an existing API.

from func_args.api import REQ, OPT, prepare_kwargs

# Suppose this is a third-party API you cannot modify:
def put_object(Bucket, Key, Body, Metadata=None, Tags=None):
    """AWS S3 put_object simplified."""
    ...

# Your enhanced wrapper:
def better_put_object(
    Bucket: str = REQ,
    Key: str = REQ,
    Body: bytes = REQ,
    Metadata: dict | None = OPT,
    Tags: dict | None = OPT,
):
    # You can add custom logic for optional params
    if Metadata is OPT:
        Metadata = {"creator": "admin"}

    kwargs = dict(
        Bucket=Bucket,
        Key=Key,
        Body=Body,
        Metadata=Metadata,
        Tags=Tags,
    )
    # prepare_kwargs will:
    # 1. Raise ParamError if any value is still REQ (caller forgot it)
    # 2. Remove any value that is still OPT (caller didn't provide it)
    # 3. Return a clean dict ready for the real API call
    return put_object(**prepare_kwargs(**kwargs))

# Works - Tags is OPT so it gets removed automatically
better_put_object(Bucket="my-bucket", Key="file.txt", Body=b"hello")

# Raises ParamError: "Missing required argument: 'Body'"
better_put_object(Bucket="my-bucket", Key="file.txt")

2. Individual Utilities

You can also use check_required and remove_optional separately:

from func_args.api import REQ, OPT, check_required, remove_optional

def create_user(username=REQ, email=REQ, nickname=OPT, role="user"):
    # Step 1: validate required params
    check_required(username=username, email=email)

    # Step 2: build kwargs and remove OPT values
    kwargs = remove_optional(
        username=username,
        email=email,
        nickname=nickname,
        role=role,
    )
    return kwargs

create_user(username="alice", email="alice@example.com")
# -> {"username": "alice", "email": "alice@example.com", "role": "user"}

create_user(username="bob", email="bob@example.com", nickname="Bobby")
# -> {"username": "bob", "email": "bob@example.com", "nickname": "Bobby", "role": "user"}

3. Enhanced Dataclasses

BaseModel and BaseFrozenModel let you define dataclasses with REQ/OPT defaults in any order — no more “fields without defaults must come before fields with defaults” restriction.

import dataclasses
from func_args.api import BaseModel, BaseFrozenModel, REQ, OPT

@dataclasses.dataclass
class DeployConfig(BaseModel):
    """
    Note: OPT fields can appear BEFORE REQ fields.
    Standard dataclasses would reject this ordering.
    """
    region: str = dataclasses.field(default=OPT)      # optional, listed first
    env: str = dataclasses.field(default="prod")       # has default
    app_name: str = dataclasses.field(default=REQ)     # required, listed last
    tags: list = dataclasses.field(default_factory=list)

# REQ fields must be provided, OPT fields are truly optional
config = DeployConfig(app_name="my-service")
assert config.app_name == "my-service"
assert config.region is OPT
assert config.env == "prod"

# to_dict() returns all fields including sentinel values
config.to_dict()
# {"region": OPT, "env": "prod", "app_name": "my-service", "tags": []}

# to_kwargs() returns only provided values (OPT filtered out)
config.to_kwargs()
# {"env": "prod", "app_name": "my-service", "tags": []}

# Missing required field raises ParamError immediately
DeployConfig()  # raises ParamError: "Field 'app_name' is required ..."

4. Frozen Dataclass with Computed Fields

@dataclasses.dataclass(frozen=True)
class Document(BaseFrozenModel):
    title: str = dataclasses.field(default=REQ)
    author: str = dataclasses.field(default=OPT)
    version: int = dataclasses.field(default=1)

    # Computed fields (init=False) work seamlessly
    slug: str = dataclasses.field(init=False)

    def __post_init__(self):
        super().__post_init__()  # validates REQ fields first
        object.__setattr__(self, "slug", self.title.lower().replace(" ", "-"))

doc = Document(title="API Guide")
assert doc.slug == "api-guide"
assert doc.to_kwargs() == {"title": "API Guide", "version": 1, "slug": "api-guide"}
# "author" excluded because it's still OPT

API Reference

Symbol

Description

REQ

Sentinel marking a required parameter

OPT

Sentinel marking an optional parameter

check_required(**kw)

Raises ParamError if any value is REQ

remove_optional(**kw)

Returns new dict with OPT values removed

prepare_kwargs(**kw)

Combines check_required + remove_optional in one pass

BaseModel

Mutable dataclass mixin with REQ/OPT support

BaseFrozenModel

Frozen (immutable) dataclass mixin with REQ/OPT support

ParamError

Exception raised for missing required parameters

AI Agent Skill

This project ships a self-contained Agent skill at .claude/skills/func-args/SKILL.md. Copy this file into your project’s .claude/skills/ directory and your AI coding agent will know how to use func_args correctly — including API usage patterns, dataclass examples, and common pitfalls.

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

func_args-1.0.2.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

func_args-1.0.2-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file func_args-1.0.2.tar.gz.

File metadata

  • Download URL: func_args-1.0.2.tar.gz
  • Upload date:
  • Size: 20.0 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":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for func_args-1.0.2.tar.gz
Algorithm Hash digest
SHA256 f46acb57f22fc0e95e6ac18c992e128f0bc207450f9cab9c02237296e0105d34
MD5 a8673b58aeba3018b2179fce319c54d6
BLAKE2b-256 9b20b6b297a845884b7f4ec3dd1f40a0b96280310efd3231b25374fbaf4fdef2

See more details on using hashes here.

File details

Details for the file func_args-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: func_args-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 15.1 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":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for func_args-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f0f36b2aea676321f436d708c39b61c4f83ddeaa31c9aef38a71898ea5fc7adb
MD5 b8ddb756abefb2c11a0e70abeea2e879
BLAKE2b-256 cb9c49269f73c85a1f934db66bda4badb5ff6aa7de2747605469f6ffa226e497

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page