$npx -y skills add One-Man-Company/Skills-ContextManager --skill python-patternsPython development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying.
| 1 | # Python Patterns |
| 2 | |
| 3 | > Python development principles and decision-making for 2025. |
| 4 | > **Learn to THINK, not memorize patterns.** |
| 5 | |
| 6 | --- |
| 7 | |
| 8 | ## ⚠️ How to Use This Skill |
| 9 | |
| 10 | This skill teaches **decision-making principles**, not fixed code to copy. |
| 11 | |
| 12 | - ASK user for framework preference when unclear |
| 13 | - Choose async vs sync based on CONTEXT |
| 14 | - Don't default to same framework every time |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## 1. Framework Selection (2025) |
| 19 | |
| 20 | ### Decision Tree |
| 21 | |
| 22 | ``` |
| 23 | What are you building? |
| 24 | │ |
| 25 | ├── API-first / Microservices |
| 26 | │ └── FastAPI (async, modern, fast) |
| 27 | │ |
| 28 | ├── Full-stack web / CMS / Admin |
| 29 | │ └── Django (batteries-included) |
| 30 | │ |
| 31 | ├── Simple / Script / Learning |
| 32 | │ └── Flask (minimal, flexible) |
| 33 | │ |
| 34 | ├── AI/ML API serving |
| 35 | │ └── FastAPI (Pydantic, async, uvicorn) |
| 36 | │ |
| 37 | └── Background workers |
| 38 | └── Celery + any framework |
| 39 | ``` |
| 40 | |
| 41 | ### Comparison Principles |
| 42 | |
| 43 | | Factor | FastAPI | Django | Flask | |
| 44 | |--------|---------|--------|-------| |
| 45 | | **Best for** | APIs, microservices | Full-stack, CMS | Simple, learning | |
| 46 | | **Async** | Native | Django 5.0+ | Via extensions | |
| 47 | | **Admin** | Manual | Built-in | Via extensions | |
| 48 | | **ORM** | Choose your own | Django ORM | Choose your own | |
| 49 | | **Learning curve** | Low | Medium | Low | |
| 50 | |
| 51 | ### Selection Questions to Ask: |
| 52 | 1. Is this API-only or full-stack? |
| 53 | 2. Need admin interface? |
| 54 | 3. Team familiar with async? |
| 55 | 4. Existing infrastructure? |
| 56 | |
| 57 | --- |
| 58 | |
| 59 | ## 2. Async vs Sync Decision |
| 60 | |
| 61 | ### When to Use Async |
| 62 | |
| 63 | ``` |
| 64 | async def is better when: |
| 65 | ├── I/O-bound operations (database, HTTP, file) |
| 66 | ├── Many concurrent connections |
| 67 | ├── Real-time features |
| 68 | ├── Microservices communication |
| 69 | └── FastAPI/Starlette/Django ASGI |
| 70 | |
| 71 | def (sync) is better when: |
| 72 | ├── CPU-bound operations |
| 73 | ├── Simple scripts |
| 74 | ├── Legacy codebase |
| 75 | ├── Team unfamiliar with async |
| 76 | └── Blocking libraries (no async version) |
| 77 | ``` |
| 78 | |
| 79 | ### The Golden Rule |
| 80 | |
| 81 | ``` |
| 82 | I/O-bound → async (waiting for external) |
| 83 | CPU-bound → sync + multiprocessing (computing) |
| 84 | |
| 85 | Don't: |
| 86 | ├── Mix sync and async carelessly |
| 87 | ├── Use sync libraries in async code |
| 88 | └── Force async for CPU work |
| 89 | ``` |
| 90 | |
| 91 | ### Async Library Selection |
| 92 | |
| 93 | | Need | Async Library | |
| 94 | |------|---------------| |
| 95 | | HTTP client | httpx | |
| 96 | | PostgreSQL | asyncpg | |
| 97 | | Redis | aioredis / redis-py async | |
| 98 | | File I/O | aiofiles | |
| 99 | | Database ORM | SQLAlchemy 2.0 async, Tortoise | |
| 100 | |
| 101 | --- |
| 102 | |
| 103 | ## 3. Type Hints Strategy |
| 104 | |
| 105 | ### When to Type |
| 106 | |
| 107 | ``` |
| 108 | Always type: |
| 109 | ├── Function parameters |
| 110 | ├── Return types |
| 111 | ├── Class attributes |
| 112 | ├── Public APIs |
| 113 | |
| 114 | Can skip: |
| 115 | ├── Local variables (let inference work) |
| 116 | ├── One-off scripts |
| 117 | ├── Tests (usually) |
| 118 | ``` |
| 119 | |
| 120 | ### Common Type Patterns |
| 121 | |
| 122 | ```python |
| 123 | # These are patterns, understand them: |
| 124 | |
| 125 | # Optional → might be None |
| 126 | from typing import Optional |
| 127 | def find_user(id: int) -> Optional[User]: ... |
| 128 | |
| 129 | # Union → one of multiple types |
| 130 | def process(data: str | dict) -> None: ... |
| 131 | |
| 132 | # Generic collections |
| 133 | def get_items() -> list[Item]: ... |
| 134 | def get_mapping() -> dict[str, int]: ... |
| 135 | |
| 136 | # Callable |
| 137 | from typing import Callable |
| 138 | def apply(fn: Callable[[int], str]) -> str: ... |
| 139 | ``` |
| 140 | |
| 141 | ### Pydantic for Validation |
| 142 | |
| 143 | ``` |
| 144 | When to use Pydantic: |
| 145 | ├── API request/response models |
| 146 | ├── Configuration/settings |
| 147 | ├── Data validation |
| 148 | ├── Serialization |
| 149 | |
| 150 | Benefits: |
| 151 | ├── Runtime validation |
| 152 | ├── Auto-generated JSON schema |
| 153 | ├── Works with FastAPI natively |
| 154 | └── Clear error messages |
| 155 | ``` |
| 156 | |
| 157 | --- |
| 158 | |
| 159 | ## 4. Project Structure Principles |
| 160 | |
| 161 | ### Structure Selection |
| 162 | |
| 163 | ``` |
| 164 | Small project / Script: |
| 165 | ├── main.py |
| 166 | ├── utils.py |
| 167 | └── requirements.txt |
| 168 | |
| 169 | Medium API: |
| 170 | ├── app/ |
| 171 | │ ├── __init__.py |
| 172 | │ ├── main.py |
| 173 | │ ├── models/ |
| 174 | │ ├── routes/ |
| 175 | │ ├── services/ |
| 176 | │ └── schemas/ |
| 177 | ├── tests/ |
| 178 | └── pyproject.toml |
| 179 | |
| 180 | Large application: |
| 181 | ├── src/ |
| 182 | │ └── myapp/ |
| 183 | │ ├── core/ |
| 184 | │ ├── api/ |
| 185 | │ ├── services/ |
| 186 | │ ├── models/ |
| 187 | │ └── ... |
| 188 | ├── tests/ |
| 189 | └── pyproject.toml |
| 190 | ``` |
| 191 | |
| 192 | ### FastAPI Structure Principles |
| 193 | |
| 194 | ``` |
| 195 | Organize by feature or layer: |
| 196 | |
| 197 | By layer: |
| 198 | ├── routes/ (API endpoints) |
| 199 | ├── services/ (business logic) |
| 200 | ├── models/ (database models) |
| 201 | ├── schemas/ (Pydantic models) |
| 202 | └── dependencies/ (shared deps) |
| 203 | |
| 204 | By feature: |
| 205 | ├── users/ |
| 206 | │ ├── routes.py |
| 207 | │ ├── service.py |
| 208 | │ └── schemas.py |
| 209 | └── products/ |
| 210 | └── ... |
| 211 | ``` |
| 212 | |
| 213 | --- |
| 214 | |
| 215 | ## 5. Django Principles (2025) |
| 216 | |
| 217 | ### Django Async (Django 5.0+) |
| 218 | |
| 219 | ``` |
| 220 | Django supports async: |
| 221 | ├── Async views |
| 222 | ├── Async middleware |
| 223 | ├── Async ORM (limited) |
| 224 | └── ASGI deployment |
| 225 | |
| 226 | When to use async in Django: |
| 227 | ├── External API calls |
| 228 | ├── WebSocket (Channels) |
| 229 | ├── High-concurrency views |
| 230 | └── Background task triggering |
| 231 | ``` |
| 232 | |
| 233 | ### Django Best Practices |
| 234 | |
| 235 | ``` |
| 236 | Model design: |
| 237 | ├── Fat models, thin views |
| 238 | ├── Use managers for common queries |
| 239 | ├── Abstract base classes for shared fields |
| 240 | |
| 241 | Views: |
| 242 | ├── Class-based for complex CRUD |
| 243 | ├── Function-based for simple endpoints |
| 244 | ├── Use viewsets with DRF |
| 245 | |
| 246 | Queries: |
| 247 | ├── select_related() for FKs |
| 248 | ├── prefetch_related() for M2M |
| 249 | ├── Avoid N+1 queries |
| 250 | └── Use .only() for specific fields |
| 251 | ``` |
| 252 | |
| 253 | --- |
| 254 | |
| 255 | ## 6. FastAPI Principles |
| 256 | |
| 257 | ### async def vs d |