bateau84/skills

python-async

Asynchronous Python with asyncio and async/await — coroutines, tasks, TaskGroup, gather, cancellation, timeouts, async context managers, concurrency limits with Semaphore, the httpx.AsyncClient, and not blocking the event loop.

查看源码

使用方法

  1. 复制安装命令,在自己的智能体环境安装前先检查源码包。
  2. 从原始文档核对所需工具、凭据和支持的宿主。
  3. 说明输入材料与期望交付物,并对照来源检查输出。
npx skills add https://github.com/bateau84/skills --skill python-async

开始前需了解

  • 安装不包含模型订阅、API 额度或访问文件的权限。
  • 仓库星数和安装量反映活跃情况,不等于独立质量或安全测试。
仓库原始内容

按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。

Pair with python-common-practice for shared verification guidance.

Persona: You are a Python async engineer. You treat the event loop as a single thread you must never block, and you make concurrency explicit.

Asynchronous Python

async/await gives concurrency for I/O-bound work (HTTP, DB, files) on one thread. It does nothing for CPU-bound work — a tight loop inside async def freezes the whole loop. Reach for async when you wait on the network, not when you crunch numbers.

The cardinal rule: never block the loop

A single synchronous call inside a coroutine stalls every other task. Diagnose these with ruff's ASYNC rules (→ See python-lint).

python
# ✗ Bad — blocks the event loop; all concurrent tasks freeze
async def fetch(url):
    return requests.get(url).json()          # sync I/O
    time.sleep(5)                            # sync sleep

# ✓ Good — yields control while waiting
async def fetch(client: httpx.AsyncClient, url):
    resp = await client.get(url)
    return resp.json()
    # await asyncio.sleep(5)  for delays

For unavoidable blocking work (a sync library, CPU work), offload it: await asyncio.to_thread(blocking_fn, arg). This keeps the loop responsive.

Run things concurrently — explicitly

awaiting calls one after another is sequential. To overlap, create tasks. Prefer asyncio.TaskGroup (3.11+): it cancels siblings on failure and propagates errors, so you never leak orphaned tasks.

python
async def fetch_all(client, ids):
    async with asyncio.TaskGroup() as tg:        # structured concurrency
        tasks = [tg.create_task(fetch(client, i)) for i in ids]
    return [t.result() for t in tasks]           # all done, errors already raised

asyncio.gather(*coros) still works but, unless return_exceptions=True, a failure leaves the other tasks running unawaited. Prefer TaskGroup for new code.

Bound concurrency — don't DoS the upstream

Unbounded gather over thousands of items opens thousands of sockets and gets you rate-limited. Cap it with a Semaphore.

python
async def fetch_bounded(client, ids, limit=10):
    sem = asyncio.Semaphore(limit)
    async def one(i):
        async with sem:                  # at most `limit` in flight
            return await fetch(client, i)
    async with asyncio.TaskGroup() as tg:
        tasks = [tg.create_task(one(i)) for i in ids]
    return [t.result() for t in tasks]

This mirrors sortarr's pipeline_concurrency setting — a configurable cap, not unbounded fan-out.

Timeouts and cancellation

Every network call needs a deadline, or one hung upstream hangs your service. Use asyncio.timeout (3.11+) as a context manager; it cancels the body on expiry.

python
async with asyncio.timeout(30):
    data = await fetch(client, url)

Cancellation arrives as asyncio.CancelledError. Never swallow it — let it propagate so structured concurrency can unwind. If you must clean up, re-raise:

python
try:
    await long_op()
except asyncio.CancelledError:
    await cleanup()
    raise                         # ✓ propagate; swallowing breaks cancellation

httpx — reuse one client

Create one AsyncClient per app/lifespan and share it; a fresh client per request throws away connection pooling and TLS reuse. Always close it (or use it as a context manager).

python
async with httpx.AsyncClient(timeout=30) as client:
    ...        # reuse across many requests

Background scheduling (APScheduler)

For periodic jobs, use AsyncIOScheduler so jobs share the app's loop rather than spawning threads. Job functions are coroutines; keep them idempotent (a missed/overlapping run shouldn't corrupt state) and let misfire_grace_time/max_instances=1 guard against pile-ups.

Common mistakes

MistakeFix
requests/time.sleep/sync DB inside async defUse async equivalents or asyncio.to_thread; ruff ASYNC flags these.
Sequential await in a loop for independent callsFan out with TaskGroup; await once.
Unbounded gather over a large listBound with asyncio.Semaphore.
except CancelledError: passRe-raise it; swallowing it breaks shutdown and timeouts.
New httpx.AsyncClient per callOne shared client per lifespan; reuse the pool.
asyncio.run() called from inside a running loopYou're already on the loop; just await.
Calling a coroutine without awaitReturns a coroutine object that never runs (and warns). Await it or make it a task.

Diagnose: 1- ruff check with the ASYNC rule set — finds blocking calls in coroutines 2- run with PYTHONASYNCIODEBUG=1 — surfaces un-awaited coroutines and slow callbacks 3- py-spy dump --pid <pid> — see where a hung event loop is stuck.

References

按任务相关推荐

来自同一仓库

更多 Skills

全部 Skills
bateau84
社区

behavioral-spec

Derive bounded, implementation-independent requirements from agreed product intent through goal refinement, coverage lenses, obstacle analysis, provenance tracking, and counterexample checks. Use to select, author, and reconcile Behavioral Requirements (BR), Quality Scenarios (QS), and Obligation Contracts (OC) without expanding scope. Not for concrete API/schema/protocol realization (use architectural-spec) or human-centered stories and scenarios (use user-stories-and-scenarios).

1小时安装量
1
GitHub Stars
0
最近更新
10月18日
bateau84
社区

desktop-ui-design

Desktop GUI design for native and hybrid applications: platform conventions (macOS HIG, Windows Fluent, GNOME HIG), menus, keyboard shortcuts, window management, session persistence, native vs Electron/Tauri trade-offs, and accessibility APIs. Use for Swift/AppKit, C/WinUI, GTK+, or Electron/Tauri/Flutter desktop design. Add web-ui-design for a web app shipped as a desktop wrapper. Not for browser-only interfaces, terminal applications (use tui-design), or command-line tools (use cli-design).

1小时安装量
1
GitHub Stars
0
最近更新
10月18日
bateau84
社区

git-commit-discipline

Small coherent commits, explanatory messages, shared-working-tree discipline, and safe undo/recovery. Use when asked to commit, when a diff mixes concerns, when agents share a working tree, or when undoing or recovering Git changes. Not for content conflicts (use git-conflicts).

1小时安装量
1
GitHub Stars
0
最近更新
10月18日
bateau84
社区

golang-dependency-injection

google/wire, uber-go/dig, uber-go/fx, samber/do, manual constructor injection, and service containers in Go. Use when designing service architecture, setting up dependency injection, refactoring tightly coupled code, or managing singletons and service factories.

1小时安装量
1
GitHub Stars
0
最近更新
10月18日