Our review
A skill that provides decision-making principles for Python development, covering framework selection, async versus sync choices, type hints, and project structure for 2025.
Strengths
- Clear decision tree for framework selection based on project type.
- Teaches principles rather than rote patterns, promoting understanding.
- Covers modern practices like Pydantic validation and async library selection.
- Includes guidance on when to use type hints and project structure sizes.
Limitations
- Relies on up-to-date knowledge of Python ecosystem as of 2025; some details may become outdated.
- Does not include specific code examples for implementation.
- Assumes familiarity with Python basics; not suitable for complete beginners.
Use this skill when planning a new Python project and needing guidance on framework choice, async approach, or project structure.
Do not use this skill for solving specific coding bugs or when you need detailed implementation code.
Security analysis
SafeThe skill is a purely educational guide on Python development principles and decision-making. It does not instruct any code execution, destructive actions, or data exfiltration. There are no declared tools, and the content is advisory only.
No concerns found
Examples
I need to build a real-time chat application using Python. Should I use FastAPI, Django, or something else? Consider async requirements.I'm writing a data pipeline that fetches from multiple APIs and processes data. Should I use async or sync? What libraries do you recommend?How should I structure a Python microservice project? I have multiple services with shared models.name: python-patterns description: Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying.
Python Patterns
π‘ MCP Tool Available: Use Context7, Tavily, BraveSearch, or Serper.dev first; only if those fail, use WebSearch or WebFetch as needed.
Python development principles and decision-making for 2025. Learn to THINK, not memorize patterns.
β οΈ How to Use This Skill
This skill teaches decision-making principles, not fixed code to copy.
- ASK user for framework preference when unclear
- Choose async vs sync based on CONTEXT
- Don't default to same framework every time
1. Framework Selection (2025)
Decision Tree
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
Comparison Principles
| 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 |
Selection Questions to Ask:
- Is this API-only or full-stack?
- Need admin interface?
- Team familiar with async?
- Existing infrastructure?
2. Async vs Sync Decision
When to Use Async
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)
The Golden Rule
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
Async Library Selection
| Need | Async Library | |------|---------------| | HTTP client | httpx | | PostgreSQL | asyncpg | | Redis | aioredis / redis-py async | | File I/O | aiofiles | | Database ORM | SQLAlchemy 2.0 async, Tortoise |
3. Type Hints Strategy
When to Type
Always type:
βββ Function parameters
βββ Return types
βββ Class attributes
βββ Public APIs
Can skip:
βββ Local variables (let inference work)
βββ One-off scripts
βββ Tests (usually)
Common Type Patterns
# 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: ...
Pydantic for Validation
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
4. Project Structure Principles
Structure Selection
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
FastAPI Structure Principles
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/
βββ ...
5. Django Principles (2025)
Django Async (Django 5.0+)
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
Django Best Practices
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
6. FastAPI Principles
async def vs def in FastAPI
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
Dependency Injection
Use dependencies for:
βββ Database sessions
βββ Current user / Auth
βββ Configuration
βββ Shared resources
Benefits:
βββ Testability (mock dependencies)
βββ Clean separation
βββ Automatic cleanup (yield)
Pydantic v2 Integration
# 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
7. Background Tasks
Selection Guide
| 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 |
When to Use Each
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
8. Error Handling Principles
Exception Strategy
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
Error Response Philosophy
Include:
βββ Error code (programmatic)
βββ Message (human readable)
βββ Details (field-level when applicable)
βββ NOT stack traces (security)
9. Testing Principles
Testing Strategy
| Type | Purpose | Tools | |------|---------|-------| | Unit | Business logic | pytest | | Integration | API endpoints | pytest + httpx/TestClient | | E2E | Full workflows | pytest + DB |
Async Testing
# 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=" as client:
response = await client.get("/users")
assert response.status_code == 200
Fixtures Strategy
Common fixtures:
βββ db_session β Database connection
βββ client β Test client
βββ authenticated_user β User with token
βββ sample_data β Test data setup
10. Decision Checklist
Before implementing:
- [ ] Asked user about framework preference?
- [ ] Chosen framework for THIS context? (not just default)
- [ ] Decided async vs sync?
- [ ] Planned type hint strategy?
- [ ] Defined project structure?
- [ ] Planned error handling?
- [ ] Considered background tasks?
11. Anti-Patterns to Avoid
β DON'T:
- Default to Django for simple APIs (FastAPI may be better)
- Use sync libraries in async code
- Skip type hints for public APIs
- Put business logic in routes/views
- Ignore N+1 queries
- Mix async and sync carelessly
β DO:
- Choose framework based on context
- Ask about async requirements
- Use Pydantic for validation
- Separate concerns (routes β services β repos)
- Test critical paths
Remember: Python patterns are about decision-making for YOUR specific context. Don't copy codeβthink about what serves your application best.
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.