Responsaas
Wraps the python responses library As A Service.
See the full documentation here (or more specifically converting from responses).
Admin UI
responsaas includes a web UI for creating and managing named mock namespaces, adding routes with JSON bodies, matchers, and callbacks, and exporting configuration as Python.
Start the server and open http://localhost:7564/__responsaas__/admin/.
Quickstart
Automatic (with pytest)
Using pytest-mock-resources, we can use Docker to manage the lifecycle of the server.
pip install responsaas[pmr]
from responsaas.pytest import create_responsaas_fixture, create_responsaas_server_fixture
responsaas_server = create_responsaas_server_fixture()
responsaas = create_responsaas_fixture()
def test_foo(responsaas: Responsaas):
responsaas.add("/foo", json={"bar": True})
response = requests.get(responsaas.base_url + "/foo")
assert response.json() == {"bar": True}
Manual
The manual examples assume you have some external way of standing up the server
pip install responsaas
import requests
from responsaas import ResponsaasServer, Responsaas
# With pytest
from responsaas.pytest import create_responsaas_fixture
responsaas = create_responsaas_fixture("http://localhost:7564")
def test_foo(responsaas: Responsaas):
responsaas.add("/foo", json={"bar": True})
response = requests.get(responsaas.base_url + "/foo")
assert response.json() == {"bar": True}
# Or completely manually.
def test_foo():
responsaas_server = ResponsaasServer("http://localhost:7564")
with responsaas_server.activate() as responsaas:
responsaas.add("/foo", json={"bar": True})
response = requests.get(responsaas.base_url + "/foo")
assert response.json() == {"bar": True}
Why?!?
Under the hood, repsonses is patching the network calls being made and
replacing their result with the result you specify. It's very fast, convenient,
and (by default) disallows you from making actual network calls.
However the same (patch) strategy that makes it useful has some issues.
-
This can run afoul of other libraries which perform
patchoperations. The issue history of responses has many instances (frequently withmoto), where patches get clobbered in one way or another.responsaasdoes not usepatchat all. It is a real standalone service responding to real requests.
-
Either through
patchissues, or through programmer error,responsescan be so non-invasive that API calls accidentally get made through to the original destination URL.responsaasforces you to change (or really, make configurable) the URL you're hitting for tests, which should make it impossible to hit the original destination url in tests on accident.
-
responsesallows you to return arbitrary python objects (like exceptions) which wouldn't be possible for a request to actually return.responsaas(once again), is a literal service responding to requests. The requesting client code is receiving bytes over the wire, and parsing it normally.
-
responsesis(?) limited to mocking therequestslibrary. Which doesn't cover cases likehttpx,aiohttp, etc.responsaasis client agnostic, given that it's a real service.
-
responsesneeds an additional mechanism to allow "passthru" requestsresponsaas(once again), is a literal service responding to requests, so it can only return.
How?
What's going on internally is:
- Each test registers a new "namespace" against the
responsaasserver - Each new namespace corresponds to one
responses.RequestsMock. - As incoming requests are received by the server, they're mapped to the request
shape expected by
responses, and routed directly through its request matching and responds logic.
Release files for responsaas 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| responsaas-0.2.0.tar.gz | 339.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| responsaas-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 367.4 kB
Release files / responsaas-0.2.0.tar.gz
| Download URL | responsaas-0.2.0.tar.gz |
|---|---|
| Size | 339.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c265de9018ea2c5aa4fae37f66badf69023cc185b630c3aba04e8758e694bc9a
|
|
BLAKE2b-256 checksum How to use checksums |
cb2678383271b556d508091a81e04230ff0c575c7a44ff823cf242d443537390
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 13, 2026.
Transparency logRelease files / responsaas-0.2.0-py3-none-any.whl
| Download URL | responsaas-0.2.0-py3-none-any.whl |
|---|---|
| Size | 27.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0b56be4b39c2e410b0aab920d89309de3b015b7ecda51a9554e649cca5d3bf8
|
|
BLAKE2b-256 checksum How to use checksums |
8fd3f123206d89de21c700a51960a46e5b62a360653dd3f08cd62f61323430e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 13, 2026.
Transparency log