aiohttp

raw JSON →
3.13.3 verified Tue May 12 auth: no python install: verified quickstart: stale

Async HTTP client/server framework for asyncio. Provides both a client (ClientSession) and a web server (web.Application). Current version is 3.13.3 (Jan 2026). Has removed several long-deprecated parameters that LLMs still generate.

pip install aiohttp
error ModuleNotFoundError: No module named 'aiohttp'
cause The 'aiohttp' module is not installed in the Python environment.
fix
Install the module using pip: 'pip install aiohttp'.
error AttributeError: module 'aiohttp' has no attribute 'ClientSession'
cause The script is named 'aiohttp.py', causing a conflict with the aiohttp module.
fix
Rename the script to avoid naming conflicts, e.g., 'my_script.py'.
error AttributeError: partially initialized module 'aiohttp' has no attribute 'ClientSession' (most likely due to a circular import)
cause The script is named 'aiohttp.py', leading to a circular import issue.
fix
Rename the script to a different name, such as 'my_script.py'.
error TypeError: ClientSession.__init__() got an unexpected keyword argument 'loop'
cause The 'loop' argument for `aiohttp.ClientSession` (and many `asyncio` primitives) was deprecated in `aiohttp` versions 2.x and removed in Python 3.10+ as event loops are now implicitly managed by `asyncio.run()` or `asyncio.get_running_loop()`. LLMs often generate code using this outdated parameter.
fix
Remove the loop argument from the ClientSession constructor. aiohttp will automatically use the currently running event loop. For example, change aiohttp.ClientSession(loop=my_loop) to aiohttp.ClientSession().
error AttributeError: module 'aiohttp' has no attribute 'get'
cause Direct top-level `aiohttp.get()` (or `post`, `put`, etc.) methods were removed in older `aiohttp` versions. Modern `aiohttp` client usage requires creating a `ClientSession` instance first.
fix
Instantiate aiohttp.ClientSession() and use its methods for HTTP requests. For example, change await aiohttp.get(url) to async with aiohttp.ClientSession() as session: await session.get(url).
breaking timeout= parameter must be aiohttp.ClientTimeout, not int/float. Passing timeout=30 raises AttributeError: 'int' object has no attribute 'total' at request time, not at session creation. The error is confusing and delayed.
fix timeout = aiohttp.ClientTimeout(total=30, connect=10) async with aiohttp.ClientSession(timeout=timeout) as session: ...
breaking loop= parameter removed from ClientSession, TCPConnector, and all other aiohttp objects. Was deprecated for years; removed in 3.9. LLM-generated code from older tutorials passes loop=asyncio.get_event_loop().
fix Remove all loop= arguments. aiohttp uses the running event loop automatically.
breaking read_timeout and conn_timeout constructor parameters removed from ClientSession. Replaced by ClientTimeout.
fix Use aiohttp.ClientTimeout(total=..., connect=..., sock_read=...) instead.
breaking verify_ssl=, ssl_context=, and fingerprint= parameters deprecated in request methods. Replaced by unified ssl= parameter.
fix Use ssl=False to skip verification, ssl=ssl_context for custom context, ssl=aiohttp.Fingerprint(...) for fingerprint pinning.
deprecated app.loop, request.loop, client.loop, connector.loop properties deprecated and scheduled for removal in aiohttp 4.0.
fix Use asyncio.get_event_loop() or asyncio.get_running_loop() directly.
gotcha Creating ClientSession outside of an async context (e.g. at module level or in __init__) raises DeprecationWarning and will raise RuntimeError in a future version.
fix Always create ClientSession inside an async function or use async with at the point of use.
gotcha Response body must be consumed before the response context manager exits, or the connection is left in a broken state. await resp.json() / await resp.text() / await resp.read() must be called inside the async with block.
fix Always consume the response body inside the async with session.get(...) as resp: block.
pip install aiohttp[speedups]
python os / libc variant status wheel install import disk
3.10 alpine (musl) aiohttp - - 0.44s 27.1M
3.10 alpine (musl) speedups - - 0.52s 34.7M
3.10 slim (glibc) aiohttp - - 0.32s 29M
3.10 slim (glibc) speedups - - 0.36s 38M
3.11 alpine (musl) aiohttp - - 0.64s 29.6M
3.11 alpine (musl) speedups - - 0.73s 37.8M
3.11 slim (glibc) aiohttp - - 0.51s 32M
3.11 slim (glibc) speedups - - 0.59s 41M
3.12 alpine (musl) aiohttp - - 0.77s 21.5M
3.12 alpine (musl) speedups - - 0.86s 29.6M
3.12 slim (glibc) aiohttp - - 0.70s 24M
3.12 slim (glibc) speedups - - 0.80s 33M
3.13 alpine (musl) aiohttp - - 0.80s 20.9M
3.13 alpine (musl) speedups - - 0.86s 29.0M
3.13 slim (glibc) aiohttp - - 0.72s 23M
3.13 slim (glibc) speedups - - 0.78s 32M
3.9 alpine (musl) aiohttp - - 0.41s 27.3M
3.9 alpine (musl) speedups - - 0.41s 36.5M
3.9 slim (glibc) aiohttp - - 0.37s 30M
3.9 slim (glibc) speedups - - 0.41s 41M

Client with ClientTimeout and basic web server setup.

import aiohttp
import asyncio

async def main():
    timeout = aiohttp.ClientTimeout(total=30)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        async with session.get('https://httpbin.org/get') as resp:
            print(resp.status)
            data = await resp.json()
            print(data)

asyncio.run(main())

# Server
from aiohttp import web

async def handle(request):
    return web.Response(text='Hello')

app = web.Application()
app.add_routes([web.get('/', handle)])
web.run_app(app)