Python Patterns
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
code
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
code
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
code
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
code
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
python
# 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
code
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
code
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
code
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+)
code
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
code
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
code
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 wor