respx: a mock transport for HTTPX that routes on patterns, not URLs
Mock HTTPX with awesome request patterns and response side effects 🦋
At a glance
- What is it?
- respx replaces the HTTPX transport so a test can assert on how a request was made, not just on what URL was called, and it ships as a pytest plugin as well as a decorator. The limits are the same as HTTPX's own: it mocks the client, not the network.
- Who is it for?
- Adopt respx if your Python project calls HTTPX in tests and you want route patterns, side effects and call assertions rather than a single canned response, and if you already use pytest. Do not adopt it if your code uses requests or urllib rather than HTTPX, since respx patches HTTPX and HTTP Core specifically, and do not expect it to exercise real sockets or real TLS.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 98 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
It patches the transport, not the function you call
respx describes itself as a utility for mocking out the HTTPX and HTTP Core libraries, and the word that matters is transport. HTTPX is built on HTTP Core, and the request path runs through a transport layer that is swappable. By patching that layer, respx intercepts a call before a socket is opened, which means the test never touches the network and never needs a live server. The alternative approach, which many projects use, is to inject a fake client object into the code under test. That approach requires the production code to accept an injected client, which means changing the shape of your own code to make it testable. respx asks for no changes to production code at all, and the cost of that convenience is that the code under test must be calling HTTPX, or something that calls HTTPX, rather than a different library. The README is explicit that the utility covers HTTPX and HTTP Core, and the setup.py description repeats it: a utility for mocking out the Python HTTPX and HTTP Core libraries.
The decorator pattern turns a route into an assertable object
The quickstart shows the whole shape in a dozen lines. You import httpx and respx, decorate the test function with respx.mock, register a route, call httpx.get, and then assert on the route object as well as on the response:
import httpx
import respx
from httpx import Response
@respx.mock
def test_example():
my_route = respx.get("https://example.org/").mock(return_value=Response(204))
response = httpx.get("https://example.org/")
assert my_route.called
assert response.status_code == 204The route object is the interesting part. Registering a route with respx.get returns a handle, and the handle records whether it was called, so a test can assert both that the right response came back and that the request was actually made. That is a meaningful difference from a stub that always returns something, because it lets you test that a code path did not make a call it should have avoided. The .mock call attaches the response behaviour to the route, and the response is a plain httpx.Response, so nothing about how you construct expected responses changes from what you would write against HTTPX directly.
The pytest plugin and the respx marker
For pytest users there is a second, tidier route. respx ships a respx_mock fixture, and the setup.py registers a pytest11 entry point pointing at respx.plugin, so the fixture is available as soon as the package is installed and no conftest change is needed. The fixture form looks like this:
import httpx
import pytest
def test_default(respx_mock):
respx_mock.get("https://foo.bar/").mock(return_value=httpx.Response(204))
response = httpx.get("https://foo.bar/")
assert response.status_code == 204
@pytest.mark.respx(base_url="https://foo.bar")
def test_with_marker(respx_mock):
respx_mock.get("/baz/").mock(return_value=httpx.Response(204))
response = httpx.get("https://foo.bar/baz/")
assert response.status_code == 204The marker is the part worth knowing about. Applying pytest.mark.respx with a base_url changes the base the mock matches against, and the route is then registered as a relative path. That is not a small convenience: it separates the host your production code talks about from the route in the test, so changing a domain in the test does not require rewriting every route. The README describes the marker as optional and points to the API reference for the full set of mock settings, which is where the configuration knobs are documented rather than in the README itself.
Installation is one pip command with two version floors
The install step is a single command:
$ pip install respxTwo requirements follow it. The library requires Python 3.8 or later and HTTPX 0.25 or later, and the setup.py confirms the Python floor with python_requires set to >=3.8 and the runtime dependency declared as httpx>=0.25.0. The Python version is not a soft preference, because the package classifiers list every supported minor version individually, from 3.8 through 3.14, and the trove classifier marks the project as Development Status 5, Production/Stable. For older HTTPX versions the README points to the changelog for the compatibility history, which is worth reading if you are pinning an old HTTPX for other reasons. The package is published on PyPI as respx, and the source layout shows a conventional setuptools project with a respx package directory, tests, a docs directory, a noxfile for test automation, a Taskfile for task running, and both flake.nix and a flake.lock for a Nix development shell.
Pattern matching is the reason to use respx over a stub
The project tagline promises request patterns and response side effects, and those are the two features that separate it from a plain return-value mock. Pattern routing means a route can be declared by more than an exact URL, so a test can match on a method, a host, a path fragment or a combination, and the routing documentation lives in the user guide. Side effects mean a route can do more than return a fixed response, for example raising an exception or returning different responses in sequence, which is what you need to test retry logic and error branches. The route object returned when you register a route is also the assertion surface, so a test can check what was sent. The honest caveat is that none of this is described in detail in the README. The README gives the quickstart and points to the user guide for a complete walk-through, so the pattern syntax and the side effect catalogue have to be looked up in the documentation rather than discovered from the README.
What respx cannot mock
The boundary of the tool is the same as the boundary of HTTPX itself, and it is worth being clear about before you adopt it. respx intercepts at the transport layer, so anything below that layer is not exercised: no real socket is opened, no DNS resolution happens, and no TLS handshake is performed. That means a test using respx will not catch a certificate problem, a proxy misconfiguration, an HTTP/2 negotiation issue or a redirect that is handled below the client. It also means respx does not help if your code does not use HTTPX. A project that calls requests, or urllib, or a synchronous wrapper around them, gets nothing from this library, and would need a different mocking approach or a migration. There is a second, subtler limit: because the transport is replaced, a test can pass while the real request would have failed on something respx never models. respx is a tool for asserting on client behaviour, not a substitute for an integration test against a real service.
BSD-3-Clause, a recent release line, and a slower patch cadence
The licence is BSD-3-Clause, stated in setup.py, in the LICENSE.md file and in the package classifier for an OSI approved BSD licence, which makes it a low-friction dependency for most organisations. The package metadata also notes that the library is OS Independent and typed, with a py.typed marker shipped as package data, so type checkers will use the inline annotations. On maintenance, the repository is not archived and the last push was on 2026-07-21. The release history shows the shape of the project: 0.22.0 on 2024-12-19, then 0.23.0 and 0.23.1 within a day of each other in April 2026, both in 2026. Two patch releases one day apart suggests a maintenance burst rather than a steady stream, so you should not expect frequent releases. The documentation is built with mkdocs, with mkdocs.yaml at the root and the published site at lundberg.github.io/respx, and the project keeps a CHANGELOG.md and a CONTRIBUTING.md alongside a pre-commit configuration, so the tooling around the code is in good shape even if the release cadence is quiet.
Editorial conclusion
Adopt respx if your Python project calls HTTPX in tests and you want route patterns, side effects and call assertions rather than a single canned response, and if you already use pytest. Do not adopt it if your code uses requests or urllib rather than HTTPX, since respx patches HTTPX and HTTP Core specifically, and do not expect it to exercise real sockets or real TLS. Before you commit, check that your HTTPX version is 0.25 or later and your Python is 3.8 or later, and read the changelog for older HTTPX compatibility, since the project lists both as hard requirements.
Frequently asked questions
What is respx?
It is a Python utility for mocking out the HTTPX and HTTP Core libraries, licensed under BSD-3-Clause and published on PyPI as respx. It patches the transport so requests are intercepted without a network call, and it also provides a pytest plugin.
How do I install respx and what does it need?
Install it with pip install respx. The library requires Python 3.8 or later and HTTPX 0.25 or later, and the changelog covers compatibility with older HTTPX versions.
How do I use respx with pytest?
The package registers a pytest plugin, so the respx_mock fixture is available after installation. You register a route on the fixture, for example respx_mock.get("https://foo.bar/").mock(return_value=httpx.Response(204)), and the optional pytest.mark.respx marker can set a base_url for relative routes.
Does respx work with the requests library?
No. The utility targets HTTPX and HTTP Core specifically, patching the HTTPX transport. Code that uses requests or urllib is not intercepted, and neither is anything below the transport layer, such as real sockets, DNS or TLS.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lundberg-respx)Was this useful?