Mock aiohttp HTTP requests by routing them through a real aiohttp.web test server. Inspired by aioresponses, with a largely compatible API.
import aiohttp
from aiointercept import aiointercept
async with aiointercept() as m:
m.get(f"{m.server_url}/users", payload=[{"id": 1}])
async with aiohttp.ClientSession() as session:
resp = await session.get(f"{m.server_url}/users")
assert await resp.json() == [{"id": 1}]Testing code that makes HTTP requests usually means either hitting a real server (slow, fragile, requires network) or replacing the HTTP layer with fake objects (fast, but disconnected from reality).
aiointercept takes a third path: it starts a real aiohttp.web server on localhost and redirects your client's requests to it — either by pointing the client at m.server_url directly, or by patching the DNS resolver so existing URLs are transparently intercepted. Your code runs its full HTTP stack; only the remote endpoint is replaced.
- Real serialization. Headers, body encoding, and content-type negotiation all go through the actual aiohttp stack.
- Inspectable requests. Callbacks receive a real
aiohttp.web.Request— read the body, headers, and query params the server saw. - Minimal patching. The default mode touches nothing globally. When you need to intercept hardcoded URLs, only the DNS resolver is patched, so redirects and connection pooling still behave as in production.
pip install aiointerceptRequirements: Python ≥ 3.10, aiohttp ≥ 3.13.
Full documentation is at aiointercept.readthedocs.io:
- Quickstart — context manager, decorator, pytest fixture, and
start()/stop()usage. - Usage guide — interception modes, registering responses, regex patterns, callbacks, and passthrough.
- Assertions —
assert_called_withand friends. - API reference — every public class and method.
Starting and stopping a server for every test adds up. aiointercept ships an
auto-discovered pytest plugin (requires pytest-asyncio) that starts the server
once per session and hands each test a cleared mock via the
aiointercept_mock fixture:
async def test_users(aiointercept_mock):
m = aiointercept_mock
m.get(f"{m.server_url}/users", payload=[{"id": 1}])
async with aiohttp.ClientSession() as session:
resp = await session.get(f"{m.server_url}/users")
assert await resp.json() == [{"id": 1}]The fixture calls m.clear() between tests, so registered handlers and recorded
requests never leak from one test to the next. The session-scoped server itself
is exposed as aiointercept_server if you need it directly.
aiointercept aims to be a near drop-in replacement. The migration guide (MIGRATING.md) covers every breaking change. If you hit an incompatibility it doesn't cover, please open an issue.
uv sync --group dev --group tests # install everything
uv run pytest tests/ # run the suite
uv run ruff check . # lint
uv run mypy aiointercept # type checkPre-commit hooks run ruff and mypy on every commit; do not bypass them with --no-verify.
aiointercept is released under the MIT License.
Built on ideas and API conventions from aioresponses by Pawel Nuckowski (MIT License). tests/test_aioresponse.py is a lightly adapted port of the original test suite, used to verify compatibility.