Python API Design
Core Principles
-
Simplicity: Simple things simple, complex things possible
-
Consistency: Similar operations work similarly
-
Least Surprise: Behave as users expect
-
Discoverability: Find via autocomplete and help
Progressive Disclosure Pattern
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
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
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
import warnings
def old_function(): warnings.warn( "old_function() deprecated, use new_function()", DeprecationWarning, stacklevel=2, ) return new_function()
Anti-Patterns
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 - Builder, factory, and advanced patterns
-
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 section of the Guide to Developing High-Quality Python Libraries by Will McGinnis.