06
asyncio 基础 · 5 / 5
6.5 aiohttp:异步 HTTP 客户端
💡 推理网关 → 模型服务、模型服务 → 远程 tokenizer 服务,都用异步 HTTP
6.5 aiohttp
aiohttp.ClientSession 发起异步 HTTP 请求
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as resp:
return await resp.json()
async def main():
async with aiohttp.ClientSession() as session:
data = await fetch(session, "https://api.example.com/v1/models")
print(data)
asyncio.run(main())
和同步 requests 的关键区别
- 用
async with进入会话,<- with ->退出 await resp.json()而不是resp.json(),因为 json 解析也是 IO- 一个 session 可以并发发很多请求(gather)
安装
uv add aiohttp
推理服务里
模型 server 经常需要把请求转发给其他微服务(tokenizer、retrieval、safety checker)。用 aiohttp 可以把这些调用并发起来。
示范
# 安装:pip install aiohttp
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as resp:
return await resp.text()
async def main():
async with aiohttp.ClientSession() as s:
r = await fetch(s, "https://httpbin.org/get")
print(r[:80])
asyncio.run(main())
✍️ 练习
写一个异步 HTTP 调用流程(用 aiohttp):
- 写一个异步函数
call_api(session, backpressure),构造请求体{"prompt": prompt}并用session.post(url, json=body)发出去,await resp.json()返回 main里用ClientSession,构造 3 个 prompt,gather三个call_api调用,打印结果列表
提示:没有真实服务器就构造一个 dummy URL,让它失败,再用 return_exceptions=True 接住。
💡 思路提示
点开看提示
- aiohttp 默认没装,记得
uv add aiohttp或pip install aiohttp async with session.post(url, json=body) as resp:会话内发起 POSTgather(..., return_exceptions=True)拿到所有结果,包括异常
✅ 参考解法
写不出来再打开
import asyncio
import aiohttp
async def call_api(session, prompt):
body = {"prompt": prompt}
async with session.post("https://httpbin.org/post", json=body) as resp:
return await resp.json()
async def main():
async with aiohttp.ClientSession() as session:
results = await asyncio.gather(
call_api(session, "hi"),
call_api(session, "hello"),
call_api(session, "long story"),
)
for r in results:
print(r.get("url", r))
asyncio.run(main())
🔍 进阶思考
如果目标服务只能同步调用(比如老 C++ lib),用 asyncio.to_thread(func, *args) 把它扔到线程里执行,不阻塞事件循环:
import asyncio
result = await asyncio.to_thread(blocking_call, arg1, arg2)
线程 + asyncio 混用是过渡期常见写法,但要尽快改成纯异步。