{"id":"4708dc6c-7ac9-4ade-9695-e743d34380c6","shortId":"CqQNF4","kind":"skill","title":"python-patterns","tagline":"Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying.","description":"# Python Patterns\n\n> Python development principles and decision-making for 2025.\n> **Learn to THINK, not memorize patterns.**\n\n## When to Use\nUse this skill when making Python architecture decisions, choosing frameworks, designing async patterns, or structuring Python projects.\n\n---\n\n## ⚠️ How to Use This Skill\n\nThis skill teaches **decision-making principles**, not fixed code to copy.\n\n- ASK user for framework preference when unclear\n- Choose async vs sync based on CONTEXT\n- Don't default to same framework every time\n\n---\n\n## 1. Framework Selection (2025)\n\n### Decision Tree\n\n```\nWhat are you building?\n│\n├── API-first / Microservices\n│   └── FastAPI (async, modern, fast)\n│\n├── Full-stack web / CMS / Admin\n│   └── Django (batteries-included)\n│\n├── Simple / Script / Learning\n│   └── Flask (minimal, flexible)\n│\n├── AI/ML API serving\n│   └── FastAPI (Pydantic, async, uvicorn)\n│\n└── Background workers\n    └── Celery + any framework\n```\n\n### Comparison Principles\n\n| Factor | FastAPI | Django | Flask |\n|--------|---------|--------|-------|\n| **Best for** | APIs, microservices | Full-stack, CMS | Simple, learning |\n| **Async** | Native | Django 5.0+ | Via extensions |\n| **Admin** | Manual | Built-in | Via extensions |\n| **ORM** | Choose your own | Django ORM | Choose your own |\n| **Learning curve** | Low | Medium | Low |\n\n### Selection Questions to Ask:\n1. Is this API-only or full-stack?\n2. Need admin interface?\n3. Team familiar with async?\n4. Existing infrastructure?\n\n---\n\n## 2. Async vs Sync Decision\n\n### When to Use Async\n\n```\nasync def is better when:\n├── I/O-bound operations (database, HTTP, file)\n├── Many concurrent connections\n├── Real-time features\n├── Microservices communication\n└── FastAPI/Starlette/Django ASGI\n\ndef (sync) is better when:\n├── CPU-bound operations\n├── Simple scripts\n├── Legacy codebase\n├── Team unfamiliar with async\n└── Blocking libraries (no async version)\n```\n\n### The Golden Rule\n\n```\nI/O-bound → async (waiting for external)\nCPU-bound → sync + multiprocessing (computing)\n\nDon't:\n├── Mix sync and async carelessly\n├── Use sync libraries in async code\n└── Force async for CPU work\n```\n\n### Async Library Selection\n\n| Need | Async Library |\n|------|---------------|\n| HTTP client | httpx |\n| PostgreSQL | asyncpg |\n| Redis | aioredis / redis-py async |\n| File I/O | aiofiles |\n| Database ORM | SQLAlchemy 2.0 async, Tortoise |\n\n---\n\n## 3. Type Hints Strategy\n\n### When to Type\n\n```\nAlways type:\n├── Function parameters\n├── Return types\n├── Class attributes\n├── Public APIs\n\nCan skip:\n├── Local variables (let inference work)\n├── One-off scripts\n├── Tests (usually)\n```\n\n### Common Type Patterns\n\n```python\n# These are patterns, understand them:\n\n# Optional → might be None\nfrom typing import Optional\ndef find_user(id: int) -> Optional[User]: ...\n\n# Union → one of multiple types\ndef process(data: str | dict) -> None: ...\n\n# Generic collections\ndef get_items() -> list[Item]: ...\ndef get_mapping() -> dict[str, int]: ...\n\n# Callable\nfrom typing import Callable\ndef apply(fn: Callable[[int], str]) -> str: ...\n```\n\n### Pydantic for Validation\n\n```\nWhen to use Pydantic:\n├── API request/response models\n├── Configuration/settings\n├── Data validation\n├── Serialization\n\nBenefits:\n├── Runtime validation\n├── Auto-generated JSON schema\n├── Works with FastAPI natively\n└── Clear error messages\n```\n\n---\n\n## 4. Project Structure Principles\n\n### Structure Selection\n\n```\nSmall project / Script:\n├── main.py\n├── utils.py\n└── requirements.txt\n\nMedium API:\n├── app/\n│   ├── __init__.py\n│   ├── main.py\n│   ├── models/\n│   ├── routes/\n│   ├── services/\n│   └── schemas/\n├── tests/\n└── pyproject.toml\n\nLarge application:\n├── src/\n│   └── myapp/\n│       ├── core/\n│       ├── api/\n│       ├── services/\n│       ├── models/\n│       └── ...\n├── tests/\n└── pyproject.toml\n```\n\n### FastAPI Structure Principles\n\n```\nOrganize by feature or layer:\n\nBy layer:\n├── routes/ (API endpoints)\n├── services/ (business logic)\n├── models/ (database models)\n├── schemas/ (Pydantic models)\n└── dependencies/ (shared deps)\n\nBy feature:\n├── users/\n│   ├── routes.py\n│   ├── service.py\n│   └── schemas.py\n└── products/\n    └── ...\n```\n\n---\n\n## 5. Django Principles (2025)\n\n### Django Async (Django 5.0+)\n\n```\nDjango supports async:\n├── Async views\n├── Async middleware\n├── Async ORM (limited)\n└── ASGI deployment\n\nWhen to use async in Django:\n├── External API calls\n├── WebSocket (Channels)\n├── High-concurrency views\n└── Background task triggering\n```\n\n### Django Best Practices\n\n```\nModel design:\n├── Fat models, thin views\n├── Use managers for common queries\n├── Abstract base classes for shared fields\n\nViews:\n├── Class-based for complex CRUD\n├── Function-based for simple endpoints\n├── Use viewsets with DRF\n\nQueries:\n├── select_related() for FKs\n├── prefetch_related() for M2M\n├── Avoid N+1 queries\n└── Use .only() for specific fields\n```\n\n---\n\n## 6. FastAPI Principles\n\n### async def vs def in FastAPI\n\n```\nUse async def when:\n├── Using async database drivers\n├── Making async HTTP calls\n├── I/O-bound operations\n└── Want to handle concurrency\n\nUse def when:\n├── Blocking operations\n├── Sync database drivers\n├── CPU-bound work\n└── FastAPI runs in threadpool automatically\n```\n\n### Dependency Injection\n\n```\nUse dependencies for:\n├── Database sessions\n├── Current user / Auth\n├── Configuration\n├── Shared resources\n\nBenefits:\n├── Testability (mock dependencies)\n├── Clean separation\n├── Automatic cleanup (yield)\n```\n\n### Pydantic v2 Integration\n\n```python\n# FastAPI + Pydantic are tightly integrated:\n\n# Request validation\n@app.post(\"/users\")\nasync def create(user: UserCreate) -> UserResponse:\n    # user is already validated\n    ...\n\n# Response serialization\n# Return type becomes response schema\n```\n\n---\n\n## 7. Background Tasks\n\n### Selection Guide\n\n| Solution | Best For |\n|----------|----------|\n| **BackgroundTasks** | Simple, in-process tasks |\n| **Celery** | Distributed, complex workflows |\n| **ARQ** | Async, Redis-based |\n| **RQ** | Simple Redis queue |\n| **Dramatiq** | Actor-based, simpler than Celery |\n\n### When to Use Each\n\n```\nFastAPI BackgroundTasks:\n├── Quick operations\n├── No persistence needed\n├── Fire-and-forget\n└── Same process\n\nCelery/ARQ:\n├── Long-running tasks\n├── Need retry logic\n├── Distributed workers\n├── Persistent queue\n└── Complex workflows\n```\n\n---\n\n## 8. Error Handling Principles\n\n### Exception Strategy\n\n```\nIn FastAPI:\n├── Create custom exception classes\n├── Register exception handlers\n├── Return consistent error format\n└── Log without exposing internals\n\nPattern:\n├── Raise domain exceptions in services\n├── Catch and transform in handlers\n└── Client gets clean error response\n```\n\n### Error Response Philosophy\n\n```\nInclude:\n├── Error code (programmatic)\n├── Message (human readable)\n├── Details (field-level when applicable)\n└── NOT stack traces (security)\n```\n\n---\n\n## 9. Testing Principles\n\n### Testing Strategy\n\n| Type | Purpose | Tools |\n|------|---------|-------|\n| **Unit** | Business logic | pytest |\n| **Integration** | API endpoints | pytest + httpx/TestClient |\n| **E2E** | Full workflows | pytest + DB |\n\n### Async Testing\n\n```python\n# Use pytest-asyncio for async tests\n\nimport pytest\nfrom httpx import AsyncClient\n\n@pytest.mark.asyncio\nasync def test_endpoint():\n    async with AsyncClient(app=app, base_url=\"http://test\") as client:\n        response = await client.get(\"/users\")\n        assert response.status_code == 200\n```\n\n### Fixtures Strategy\n\n```\nCommon fixtures:\n├── db_session → Database connection\n├── client → Test client\n├── authenticated_user → User with token\n└── sample_data → Test data setup\n```\n\n---\n\n## 10. Decision Checklist\n\nBefore implementing:\n\n- [ ] **Asked user about framework preference?**\n- [ ] **Chosen framework for THIS context?** (not just default)\n- [ ] **Decided async vs sync?**\n- [ ] **Planned type hint strategy?**\n- [ ] **Defined project structure?**\n- [ ] **Planned error handling?**\n- [ ] **Considered background tasks?**\n\n---\n\n## 11. Anti-Patterns to Avoid\n\n### ❌ DON'T:\n- Default to Django for simple APIs (FastAPI may be better)\n- Use sync libraries in async code\n- Skip type hints for public APIs\n- Put business logic in routes/views\n- Ignore N+1 queries\n- Mix async and sync carelessly\n\n### ✅ DO:\n- Choose framework based on context\n- Ask about async requirements\n- Use Pydantic for validation\n- Separate concerns (routes → services → repos)\n- Test critical paths\n\n---\n\n> **Remember**: Python patterns are about decision-making for YOUR specific context. Don't copy code—think about what serves your application best.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["python","patterns","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-python-patterns","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/python-patterns","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34616 github stars · SKILL.md body (8,868 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-23T00:51:27.136Z","embedding":null,"createdAt":"2026-04-18T21:43:06.753Z","updatedAt":"2026-04-23T00:51:27.136Z","lastSeenAt":"2026-04-23T00:51:27.136Z","tsv":"'+1':595,976 '/users':680,878 '1':99,192 '10':904 '11':939 '2':202,214 '2.0':321 '200':882 '2025':33,102,512 '3':206,324 '4':211,443 '5':509 '5.0':164,516 '6':602 '7':698 '8':763 '9':822 'abstract':561 'actor':727 'actor-bas':726 'admin':122,167,204 'ai/ml':133 'aiofil':317 'aioredi':310 'alreadi':689 'alway':331 'anti':941 'anti-pattern':940 'api':110,134,153,196,340,421,456,472,488,536,835,952,968 'api-first':109 'api-on':195 'app':457,868,869 'app.post':679 'appli':408 'applic':468,817,1026 'architectur':49 'arq':716 'asgi':243,527 'ask':77,191,909,989,1061 'assert':879 'async':13,54,85,114,138,161,210,215,222,223,260,264,270,285,291,294,298,302,314,322,514,519,520,522,524,532,605,612,616,620,681,717,844,852,861,865,923,961,979,991 'asynccli':859,867 'asyncio':850 'asyncpg':308 'attribut':338 'auth':655 'authent':894 'auto':432 'auto-gener':431 'automat':645,665 'avoid':593,944 'await':876 'background':140,544,699,937 'backgroundtask':706,737 'base':88,562,570,576,720,728,870,986 'batteri':125 'batteries-includ':124 'becom':695 'benefit':428,659 'best':151,548,704,1027 'better':226,247,956 'block':261,632 'bound':251,276,639 'boundari':1069 'build':108 'built':170 'built-in':169 'busi':491,831,970 'call':537,622 'callabl':402,406,410 'careless':286,982 'catch':792 'celeri':142,712,731 'celery/arq':749 'channel':539 'checklist':906 'choos':51,84,175,180,984 'chosen':914 'clarif':1063 'class':337,563,569,774 'class-bas':568 'clean':663,799 'cleanup':666 'clear':440,1036 'client':305,797,874,891,893 'client.get':877 'cms':121,158 'code':74,292,807,881,962,1020 'codebas':256 'collect':390 'common':354,559,885 'communic':241 'comparison':145 'complex':572,714,761 'comput':279 'concern':998 'concurr':234,542,628 'configur':656 'configuration/settings':424 'connect':235,890 'consid':936 'consist':779 'context':90,918,988,1016 'copi':22,76,1019 'core':471 'cpu':250,275,296,638 'cpu-bound':249,274,637 'creat':683,771 'criteria':1072 'critic':1003 'crud':573 'current':653 'curv':184 'custom':772 'data':385,425,900,902 'databas':230,318,494,617,635,651,889 'db':843,887 'decid':922 'decis':9,30,50,69,103,218,905,1011 'decision-mak':8,29,68,1010 'def':224,244,371,383,391,396,407,606,608,613,630,682,862 'default':93,921,947 'defin':930 'dep':501 'depend':499,646,649,662 'deploy':528 'describ':1040 'design':53,551 'detail':812 'develop':5,26 'dict':387,399 'distribut':713,757 'django':123,149,163,178,510,513,515,517,534,547,949 'domain':788 'dramatiq':725 'drf':583 'driver':618,636 'e2e':839 'endpoint':489,579,836,864 'environ':1052 'environment-specif':1051 'error':441,764,780,800,802,806,934 'everi':97 'except':767,773,776,789 'exist':212 'expert':1057 'expos':784 'extens':166,173 'extern':273,535 'factor':147 'familiar':208 'fast':116 'fastapi':113,136,148,438,477,603,610,641,672,736,770,953 'fastapi/starlette/django':242 'fat':552 'featur':239,482,503 'field':566,601,814 'field-level':813 'file':232,315 'find':372 'fire':744 'fire-and-forget':743 'first':111 'fix':73 'fixtur':883,886 'fks':588 'flask':130,150 'flexibl':132 'fn':409 'forc':293 'forget':746 'format':781 'framework':11,52,80,96,100,144,912,915,985 'full':118,156,200,840 'full-stack':117,155,199 'function':333,575 'function-bas':574 'generat':433 'generic':389 'get':392,397,798 'golden':267 'guid':702 'handl':627,765,935 'handler':777,796 'high':541 'high-concurr':540 'hint':16,326,928,965 'http':231,304,621 'httpx':306,857 'httpx/testclient':838 'human':810 'i/o':316 'i/o-bound':228,269,623 'id':374 'ignor':974 'implement':908 'import':369,405,854,858 'in-process':708 'includ':126,805 'infer':346 'infrastructur':213 'init':458 'inject':647 'input':1066 'int':375,401,411 'integr':670,676,834 'interfac':205 'intern':785 'item':393,395 'json':434 'larg':467 'layer':484,486 'learn':34,129,160,183 'legaci':255 'let':345 'level':815 'librari':262,289,299,303,959 'limit':526,1028 'list':394 'local':343 'log':782 'logic':492,756,832,971 'long':751 'long-run':750 'low':185,187 'm2m':592 'main.py':452,460 'make':10,31,47,70,619,1012 'manag':557 'mani':233 'manual':168 'map':398 'match':1037 'may':954 'medium':186,455 'memor':38 'messag':442,809 'microservic':112,154,240 'middlewar':523 'might':364 'minim':131 'miss':1074 'mix':282,978 'mock':661 'model':423,461,474,493,495,498,550,553 'modern':115 'multipl':381 'multiprocess':278 'myapp':470 'n':594,975 'nativ':162,439 'need':203,301,742,754 'none':366,388 'one':349,379 'one-off':348 'oper':229,252,624,633,739 'option':363,370,376 'organ':480 'orm':174,179,319,525 'output':1046 'paramet':334 'path':1004 'pattern':3,14,24,39,55,356,360,786,942,1007 'permiss':1067 'persist':741,759 'philosophi':804 'plan':926,933 'postgresql':307 'practic':549 'prefer':81,913 'prefetch':589 'principl':6,27,71,146,446,479,511,604,766,824 'process':384,710,748 'product':508 'programmat':808 'project':17,59,444,450,931 'public':339,967 'purpos':828 'put':969 'py':313,459 'pydant':137,414,420,497,668,673,994 'pyproject.toml':466,476 'pytest':833,837,842,849,855 'pytest-asyncio':848 'pytest.mark.asyncio':860 'python':2,4,23,25,48,58,357,671,846,1006 'python-pattern':1 'queri':560,584,596,977 'question':189 'queue':724,760 'quick':738 'rais':787 'readabl':811 'real':237 'real-tim':236 'redi':309,312,719,723 'redis-bas':718 'redis-pi':311 'regist':775 'relat':586,590 'rememb':1005 'repo':1001 'request':677 'request/response':422 'requir':992,1065 'requirements.txt':454 'resourc':658 'respons':691,696,801,803,875 'response.status':880 'retri':755 'return':335,693,778 'review':1058 'rout':462,487,999 'routes.py':505 'routes/views':973 'rq':721 'rule':268 'run':642,752 'runtim':429 'safeti':1068 'sampl':899 'schema':435,464,496,697 'schemas.py':507 'scope':1039 'script':128,254,351,451 'secur':821 'select':12,101,188,300,448,585,701 'separ':664,997 'serial':427,692 'serv':135,1024 'servic':463,473,490,791,1000 'service.py':506 'session':652,888 'setup':903 'share':500,565,657 'simpl':127,159,253,578,707,722,951 'simpler':729 'skill':45,64,66,1031 'skill-python-patterns' 'skip':342,963 'small':449 'solut':703 'source-sickn33' 'specif':600,1015,1053 'sqlalchemi':320 'src':469 'stack':119,157,201,819 'stop':1059 'str':386,400,412,413 'strategi':327,768,826,884,929 'structur':18,57,445,447,478,932 'substitut':1049 'success':1071 'support':518 'sync':87,217,245,277,283,288,634,925,958,981 'task':545,700,711,753,938,1035 'teach':19,67 'team':207,257 'test':352,465,475,823,825,845,853,863,872,892,901,1002,1055 'testabl':660 'thin':554 'think':20,36,1021 'threadpool':644 'tight':675 'time':98,238 'token':898 'tool':829 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'tortois':323 'trace':820 'transform':794 'treat':1044 'tree':104 'trigger':546 'type':15,325,330,332,336,355,368,382,404,694,827,927,964 'unclear':83 'understand':361 'unfamiliar':258 'union':378 'unit':830 'url':871 'use':42,43,62,221,287,419,531,556,580,597,611,615,629,648,734,847,957,993,1029 'user':78,373,377,504,654,684,687,895,896,910 'usercr':685 'userrespons':686 'usual':353 'utils.py':453 'uvicorn':139 'v2':669 'valid':416,426,430,678,690,996,1054 'variabl':344 'version':265 'via':165,172 'view':521,543,555,567 'viewset':581 'vs':86,216,607,924 'wait':271 'want':625 'web':120 'websocket':538 'without':783 'work':297,347,436,640 'worker':141,758 'workflow':715,762,841 'yield':667","prices":[{"id":"4cd2bbf5-9e34-4bf2-87ff-d4235e8ab476","listingId":"4708dc6c-7ac9-4ade-9695-e743d34380c6","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:43:06.753Z"}],"sources":[{"listingId":"4708dc6c-7ac9-4ade-9695-e743d34380c6","source":"github","sourceId":"sickn33/antigravity-awesome-skills/python-patterns","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/python-patterns","isPrimary":false,"firstSeenAt":"2026-04-18T21:43:06.753Z","lastSeenAt":"2026-04-23T00:51:27.136Z"}],"details":{"listingId":"4708dc6c-7ac9-4ade-9695-e743d34380c6","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"python-patterns","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34616,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"5c69ee3486372333eb65e685a9040429482d8037","skill_md_path":"skills/python-patterns/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/python-patterns"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"python-patterns","description":"Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/python-patterns"},"updatedAt":"2026-04-23T00:51:27.136Z"}}