一键导入
python-async-patterns
Python asyncio patterns. Triggers on: asyncio, TaskGroup, gather, await, concurrent, blocking I/O, to_thread, parallel execution.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Python asyncio patterns. Triggers on: asyncio, TaskGroup, gather, await, concurrent, blocking I/O, to_thread, parallel execution.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Hexagonal Architecture (Ports & Adapters) for the video publishing pipeline. Triggers on: VideoPublisher, TrendingVideoFetcher, TimeSeriesReader, VideoMetadataReader, AuthCredentialStore, ReleaseDateValidator, OAuthProvider, publisher_registry, ports, adapters, domain, hexagonal, build_publishers, TaskGroup publish.
Type hint patterns for this repo: Protocol, TypeVar, TypedDict, Literal, Final, and strict ty usage. Triggers on: type hints, typing, TypeVar, Protocol, Generic, TypedDict, ty check.
Design, review, and optimize Dockerfiles, Docker images, and Docker Compose configurations for production, performance, and maintainability. Use when auditing Docker configurations, creating production-ready images, designing multi-container architectures, or implementing container orchestration with focus on security, reproducibility, minimal attack surface, build optimization, and observability.
Best practices for modeling, ingesting, querying, and analyzing time-series data with TinyFlux. Use when designing TinyFlux Point schemas, implementing query patterns, managing retention and partitioning, or integrating TinyFlux with pandas/NumPy for analysis and forecasting workflows.
Video processing migration (C1 split): guidelines for decomposing src/video_processing.py into src/infrastructure/video/. Triggers on: video_processing, VideoAssetManager, VideoRenderer, ThumbnailGenerator, VideoCompositor, moviepy, CompositeVideoClip, PIL Image.
Structured logging with structlog. Triggers on: log, logger, exception, structlog, observe, print, logging.
| name | python-async-patterns |
| description | Python asyncio patterns. Triggers on: asyncio, TaskGroup, gather, await, concurrent, blocking I/O, to_thread, parallel execution. |
| compatibility | Python 3.12+. TaskGroup and modern timeouts required. |
asyncio.TaskGroup instead of asyncio.gather for structural concurrency.asyncio.to_thread.TaskGroup.Unlike gather, TaskGroup does not return results from the async with block. Store task references before the context exits and call .result() after.
import asyncio
from typing import Any
async def process_all(items: list[str]) -> list[Any]:
tasks: list[asyncio.Task[Any]] = []
async with asyncio.TaskGroup() as tg:
for item in items:
tasks.append(tg.create_task(process_one(item)))
# Safe to read .result() — TaskGroup has exited successfully
return [task.result() for task in tasks]
By default, if one task raises an unhandled exception, TaskGroup cancels all remaining tasks. To isolate per-task failures, catch exceptions inside the worker coroutine.
async def _safe_process(item: str) -> Result | Exception:
try:
return await process_one(item)
except Exception as exc:
return exc # Return error as value instead of propagating
async def process_independently(items: list[str]) -> list[Result | Exception]:
tasks: list[asyncio.Task[Result | Exception]] = []
async with asyncio.TaskGroup() as tg:
for item in items:
tasks.append(tg.create_task(_safe_process(item)))
return [t.result() for t in tasks]
This is the same isolation strategy used in _publish_one for the video publishing pipeline — see hexagonal-architecture-video-publish skill.
Offload synchronous blocking calls (legacy clients, Pillow, disk I/O) to a thread with asyncio.to_thread. This is the modern replacement for loop.run_in_executor.
import asyncio
def blocking_transcode(path: str) -> str:
# CPU/disk-heavy — must not run on the event loop directly
...
async def transcode_async(path: str) -> str:
return await asyncio.to_thread(blocking_transcode, path)
Pass arguments positionally — asyncio.to_thread accepts (func, *args, **kwargs).
import asyncio
async def fetch_with_timeout() -> str | None:
try:
async with asyncio.timeout(5.0):
return await slow_network_call()
except TimeoutError:
return None
Use the built-in TimeoutError (not asyncio.TimeoutError) — they are the same in Python 3.11+. Do not use asyncio.wait_for for new code.
Use a Semaphore inside a TaskGroup when hitting rate-limited APIs.
async def bounded_fetch(urls: list[str], limit: int = 5) -> list[str]:
semaphore = asyncio.Semaphore(limit)
async def _fetch(url: str) -> str:
async with semaphore:
return await fetch_one(url)
tasks: list[asyncio.Task[str]] = []
async with asyncio.TaskGroup() as tg:
for url in urls:
tasks.append(tg.create_task(_fetch(url)))
return [t.result() for t in tasks]
| ❌ Anti-pattern | ✅ Correct |
|---|---|
await asyncio.gather(*tasks) | async with asyncio.TaskGroup() as tg: |
time.sleep(n) inside async | await asyncio.sleep(n) |
requests.get(url) inside async | async with aiohttp.ClientSession() |
loop.run_in_executor(None, fn) | await asyncio.to_thread(fn) |
asyncio.create_task(work()) (orphaned) | Keep reference or use TaskGroup |
| No per-task error handling in TaskGroup | Wrap worker in try/except returning value |
from contextlib import asynccontextmanager
@asynccontextmanager
async def managed_connection():
conn = await create_connection()
try:
yield conn
finally:
await conn.close()
hexagonal-architecture-video-publish — _publish_one fault-tolerant TaskGroup patternpython-fastapi-patterns — async route handlersvideo-processing-migration — offloading blocking media ops with to_thread