How this skill is triggered — by the user, by Claude, or both
Slash command
/faos-dev:python-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- AUTO-GENERATED by export-plugins.py — DO NOT EDIT -->
Python development principles and decision-making for 2025. Learn to THINK, not memorize patterns.
Use this skill when making Python architecture decisions, choosing frameworks, designing async patterns, or structuring Python projects.
This skill teaches decision-making principles, not fixed code to copy.
What are you building?
|
+-- API-first / Microservices
| +-- FastAPI (async, modern, fast)
|
+-- Full-stack web / CMS / Admin
| +-- Django (batteries-included)
|
+-- Simple / Script / Learning
| +-- Flask (minimal, flexible)
|
+-- AI/ML API serving
| +-- FastAPI (Pydantic, async, uvicorn)
|
+-- Background workers
+-- Celery + any framework
| Factor | FastAPI | Django | Flask |
|---|---|---|---|
| Best for | APIs, microservices | Full-stack, CMS | Simple, learning |
| Async | Native | Django 5.0+ | Via extensions |
| Admin | Manual | Built-in | Via extensions |
| ORM | Choose your own | Django ORM | Choose your own |
| Learning curve | Low | Medium | Low |
async def is better when:
+-- I/O-bound operations (database, HTTP, file)
+-- Many concurrent connections
+-- Real-time features
+-- Microservices communication
+-- FastAPI/Starlette/Django ASGI
def (sync) is better when:
+-- CPU-bound operations
+-- Simple scripts
+-- Legacy codebase
+-- Team unfamiliar with async
+-- Blocking libraries (no async version)
I/O-bound -> async (waiting for external)
CPU-bound -> sync + multiprocessing (computing)
Don't:
+-- Mix sync and async carelessly
+-- Use sync libraries in async code
+-- Force async for CPU work
| Need | Async Library |
|---|---|
| HTTP client | httpx |
| PostgreSQL | asyncpg |
| Redis | aioredis / redis-py async |
| File I/O | aiofiles |
| Database ORM | SQLAlchemy 2.0 async, Tortoise |
Always type:
+-- Function parameters
+-- Return types
+-- Class attributes
+-- Public APIs
Can skip:
+-- Local variables (let inference work)
+-- One-off scripts
+-- Tests (usually)
# These are patterns, understand them:
# Optional -> might be None
from typing import Optional
def find_user(id: int) -> Optional[User]: ...
# Union -> one of multiple types
def process(data: str | dict) -> None: ...
# Generic collections
def get_items() -> list[Item]: ...
def get_mapping() -> dict[str, int]: ...
# Callable
from typing import Callable
def apply(fn: Callable[[int], str]) -> str: ...
When to use Pydantic:
+-- API request/response models
+-- Configuration/settings
+-- Data validation
+-- Serialization
Benefits:
+-- Runtime validation
+-- Auto-generated JSON schema
+-- Works with FastAPI natively
+-- Clear error messages
Small project / Script:
+-- main.py
+-- utils.py
+-- requirements.txt
Medium API:
+-- app/
| +-- __init__.py
| +-- main.py
| +-- models/
| +-- routes/
| +-- services/
| +-- schemas/
+-- tests/
+-- pyproject.toml
Large application:
+-- src/
| +-- myapp/
| +-- core/
| +-- api/
| +-- services/
| +-- models/
| +-- ...
+-- tests/
+-- pyproject.toml
Organize by feature or layer:
By layer:
+-- routes/ (API endpoints)
+-- services/ (business logic)
+-- models/ (database models)
+-- schemas/ (Pydantic models)
+-- dependencies/ (shared deps)
By feature:
+-- users/
| +-- routes.py
| +-- service.py
| +-- schemas.py
+-- products/
+-- ...
Django supports async:
+-- Async views
+-- Async middleware
+-- Async ORM (limited)
+-- ASGI deployment
When to use async in Django:
+-- External API calls
+-- WebSocket (Channels)
+-- High-concurrency views
+-- Background task triggering
Model design:
+-- Fat models, thin views
+-- Use managers for common queries
+-- Abstract base classes for shared fields
Views:
+-- Class-based for complex CRUD
+-- Function-based for simple endpoints
+-- Use viewsets with DRF
Queries:
+-- select_related() for FKs
+-- prefetch_related() for M2M
+-- Avoid N+1 queries
+-- Use .only() for specific fields
Use async def when:
+-- Using async database drivers
+-- Making async HTTP calls
+-- I/O-bound operations
+-- Want to handle concurrency
Use def when:
+-- Blocking operations
+-- Sync database drivers
+-- CPU-bound work
+-- FastAPI runs in threadpool automatically
Use dependencies for:
+-- Database sessions
+-- Current user / Auth
+-- Configuration
+-- Shared resources
Benefits:
+-- Testability (mock dependencies)
+-- Clean separation
+-- Automatic cleanup (yield)
# FastAPI + Pydantic are tightly integrated:
# Request validation
@app.post("/users")
async def create(user: UserCreate) -> UserResponse:
# user is already validated
...
# Response serialization
# Return type becomes response schema
| Solution | Best For |
|---|---|
| BackgroundTasks | Simple, in-process tasks |
| Celery | Distributed, complex workflows |
| ARQ | Async, Redis-based |
| RQ | Simple Redis queue |
| Dramatiq | Actor-based, simpler than Celery |
FastAPI BackgroundTasks:
+-- Quick operations
+-- No persistence needed
+-- Fire-and-forget
+-- Same process
Celery/ARQ:
+-- Long-running tasks
+-- Need retry logic
+-- Distributed workers
+-- Persistent queue
+-- Complex workflows
In FastAPI:
+-- Create custom exception classes
+-- Register exception handlers
+-- Return consistent error format
+-- Log without exposing internals
Pattern:
+-- Raise domain exceptions in services
+-- Catch and transform in handlers
+-- Client gets clean error response
Include:
+-- Error code (programmatic)
+-- Message (human readable)
+-- Details (field-level when applicable)
+-- NOT stack traces (security)
| Type | Purpose | Tools |
|---|---|---|
| Unit | Business logic | pytest |
| Integration | API endpoints | pytest + httpx/TestClient |
| E2E | Full workflows | pytest + DB |
# Use pytest-asyncio for async tests
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_endpoint():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/users")
assert response.status_code == 200
Common fixtures:
+-- db_session -> Database connection
+-- client -> Test client
+-- authenticated_user -> User with token
+-- sample_data -> Test data setup
Before implementing:
Remember: Python patterns are about decision-making for YOUR specific context. Don't copy code--think about what serves your application best.
npx claudepluginhub frank-luongt/faos-skills-marketplace --plugin faos-devGuides Python architecture decisions: framework selection (FastAPI, Django, Flask), async vs sync tradeoffs, type hints strategy, and project structure principles.
Guides Python architecture decisions: framework selection (FastAPI, Django, Flask, Celery), async vs sync patterns, type hints strategies, and project structure.
Provides expert Python backend patterns for Django, FastAPI, Flask: Pydantic models, dependency injection, background tasks, exception handling, lifespan events, async programming.