home / skills / wdm0006 / python-skills / api-design

api-design skill

/skills/api-design

This skill helps design Python library APIs with simplicity, consistency, and discoverability, guiding deprecation, error handling, and versioning.

npx playbooks add skill wdm0006/python-skills --skill api-design

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.8 KB
---
name: designing-python-apis
description: Designs intuitive Python library APIs following principles of simplicity, consistency, and discoverability. Handles API evolution, deprecation, breaking changes, and error handling. Use when designing new library APIs, reviewing existing APIs for improvements, or managing API versioning and deprecations.
---

# Python API Design

## Core Principles

1. **Simplicity**: Simple things simple, complex things possible
2. **Consistency**: Similar operations work similarly
3. **Least Surprise**: Behave as users expect
4. **Discoverability**: Find via autocomplete and help

## Progressive Disclosure Pattern

```python
# Level 1: Simple functions
from mylib import encode, decode
result = encode(37.7749, -122.4194)

# Level 2: Configurable classes
from mylib import Encoder
encoder = Encoder(precision=15)

# Level 3: Low-level access
from mylib.internals import BitEncoder
```

## Naming Conventions

```python
# Actions: verbs
encode(), decode(), validate()

# Retrieval: get_*
get_user(), get_config()

# Boolean: is_*, has_*, can_*
is_valid(), has_permission()

# Conversion: to_*, from_*
to_dict(), from_json()
```

## Error Handling

```python
class MyLibError(Exception):
    """Base exception with helpful messages."""
    def __init__(self, message: str, *, hint: str = None):
        super().__init__(message)
        self.hint = hint

# Usage
raise ValidationError(
    f"Latitude must be -90 to 90, got {lat}",
    hint="Did you swap latitude and longitude?"
)
```

## Deprecation

```python
import warnings

def old_function():
    warnings.warn(
        "old_function() deprecated, use new_function()",
        DeprecationWarning,
        stacklevel=2,
    )
    return new_function()
```

## Anti-Patterns

```python
# Bad: Boolean trap
process(data, True, False, True)

# Good: Keyword arguments
process(data, validate=True, cache=False)

# Bad: Mutable default
def process(items: list = []):

# Good: None default
def process(items: list | None = None):
```

For detailed patterns, see:
- **[PATTERNS.md](PATTERNS.md)** - Builder, factory, and advanced patterns
- **[EVOLUTION.md](EVOLUTION.md)** - API versioning and migration guides

## Review Checklist

```
Naming:
- [ ] Clear, self-documenting names
- [ ] Consistent patterns throughout
- [ ] Boolean params read naturally

Parameters:
- [ ] Minimal required parameters
- [ ] Sensible defaults
- [ ] Keyword-only after positional clarity

Errors:
- [ ] Custom exceptions with context
- [ ] Helpful error messages
- [ ] Documented in docstrings
```

## Learn More

This skill is based on the [Ergonomics](https://mcginniscommawill.com/guides/python-library-development/#ergonomics-the-joy-of-good-design) section of the [Guide to Developing High-Quality Python Libraries](https://mcginniscommawill.com/guides/python-library-development/) by [Will McGinnis](https://mcginniscommawill.com/).

Overview

This skill designs intuitive Python library APIs focused on simplicity, consistency, and discoverability. It helps create progressive interfaces that expose simple defaults, configurable classes, and low-level primitives as needed. Use it to shape naming, error handling, deprecation, and API evolution so your library feels natural to use and easy to maintain.

How this skill works

The skill inspects API shapes and recommends patterns: top-level convenience functions for common cases, configurable objects for advanced use, and clear low-level modules for power users. It applies naming conventions (verbs for actions, get_ for retrieval, is_/has_ for booleans, to_/from_ for conversions), checks for anti-patterns, and generates deprecation and error-handling templates. It also produces a review checklist and migration guidance for breaking changes and versioning.

When to use it

  • Designing new library APIs to maximize ergonomics and discoverability
  • Reviewing an existing API to improve consistency and reduce surprises
  • Defining deprecation notices and migration paths during API evolution
  • Auditing error handling and exception classes for clarity and context
  • Preparing a public release and documenting expected usage patterns

Best practices

  • Favor simple top-level helpers, escalate to configurable classes, then expose low-level internals for advanced control
  • Choose self-documenting names and consistent verb/noun patterns across the surface area
  • Avoid boolean-flag overloads; prefer keyword arguments with descriptive names
  • Use immutable-safe defaults (None instead of mutable containers) and make keyword-only where appropriate
  • Provide custom exceptions with contextual messages and optional hints to aid debugging
  • Emit DeprecationWarning with clear replacement guidance and stacklevel=2 for actionable warnings

Example use cases

  • Create a minimal encode()/decode() surface for everyday use, plus an Encoder class for advanced tuning
  • Refactor a module that uses positional boolean flags into explicit keyword parameters
  • Design exception hierarchy with a shared base exception and per-case subclasses that include hints
  • Implement a deprecation wrapper that warns and forwards to the new API while documenting migration steps
  • Run the review checklist on a library prior to a major version bump to catch inconsistency and breaking-change risks

FAQ

How should I decide what belongs at the top-level API vs internals?

Expose the most common, simplest operations at top level. Progress to configurable classes for advanced customization and keep low-level primitives in clearly-named internal modules for expert use.

What’s the best way to signal breaking changes?

Document the change, provide a migration guide, emit deprecation warnings on the old API with replacement examples, and schedule removals across major releases to give users time to migrate.