python
Python patterns for backend development, testing, and async programming. Use when writing Python code.
When & Why to Use This Skill
This Claude skill provides a comprehensive set of modern Python patterns and best practices optimized for backend development, asynchronous programming, and robust testing. It streamlines the creation of maintainable, type-safe, and high-performance Python applications by enforcing industry standards such as PEP 484 type hints, pytest methodologies, and efficient async resource management.
Use Cases
- Case 1: Architecting scalable backend services using asynchronous patterns, including semaphores for rate limiting and async context managers for resource pooling.
- Case 2: Implementing type-safe data models and business logic using Python Dataclasses and Generics to minimize runtime errors and improve code clarity.
- Case 3: Developing comprehensive test suites with pytest, leveraging fixtures, parameterized testing, and advanced mocking for both sync and async functions.
- Case 4: Standardizing error handling across a codebase using custom exception hierarchies and the Result pattern for more predictable application flow.
- Case 5: Automating code quality enforcement by integrating best practices for linting (Ruff), formatting (Black), and dependency management (uv/venv).
| name | python |
|---|---|
| description | Python patterns for backend development, testing, and async programming. Use when writing Python code. |
Python
Type Hints & Dataclasses
from dataclasses import dataclass
from typing import Optional, TypeVar, Generic
@dataclass
class User:
name: str
email: str
id: Optional[str] = None
# Generic types
T = TypeVar('T')
E = TypeVar('E')
@dataclass
class Result(Generic[T, E]):
value: Optional[T] = None
error: Optional[E] = None
@property
def ok(self) -> bool:
return self.error is None
Testing (pytest)
import pytest
from unittest.mock import Mock, AsyncMock, patch
# Fixtures
@pytest.fixture
def mock_db():
return Mock()
@pytest.fixture
def user_service(mock_db):
return UserService(mock_db)
# Parameterized tests
@pytest.mark.parametrize("email,valid", [
("test@example.com", True),
("invalid", False),
])
def test_validate_email(email, valid):
assert validate_email(email) == valid
# Async tests
@pytest.mark.asyncio
async def test_fetch_user(user_service, mock_db):
mock_db.find.return_value = {"id": "1", "name": "Test"}
result = await user_service.get("1")
assert result.name == "Test"
# Mocking
@patch("myapp.services.external_api")
def test_with_mock(mock_api):
mock_api.fetch.return_value = {"status": "ok"}
Async Patterns
import asyncio
from contextlib import asynccontextmanager
# Gather with error handling
async def fetch_all(urls: list[str]) -> list[Result]:
tasks = [fetch(url) for url in urls]
return await asyncio.gather(*tasks, return_exceptions=True)
# Async context manager
@asynccontextmanager
async def get_connection():
conn = await pool.acquire()
try:
yield conn
finally:
await pool.release(conn)
# Semaphore for rate limiting
sem = asyncio.Semaphore(10)
async def limited_fetch(url):
async with sem:
return await fetch(url)
Error Handling
# Custom exceptions
class AppError(Exception):
def __init__(self, message: str, code: int = 500):
self.message = message
self.code = code
class NotFoundError(AppError):
def __init__(self, resource: str):
super().__init__(f"{resource} not found", 404)
# Result pattern
def find_user(id: str) -> Result[User, str]:
user = db.users.get(id)
if not user:
return Result(error="User not found")
return Result(value=user)
Best Practices
- Use type hints everywhere, validate with mypy
- Prefer dataclasses/Pydantic for data structures
- Use pytest fixtures for test setup
- Handle async errors with try/except in gather
- Use
loggingmodule, not print - Virtual environments mandatory (venv/uv)
- Format with ruff/black, lint with ruff