Skip to main content

Build Status PyPI

mock-response-delay

Simulate a slow server, and the client timeout it causes, in HTTP mocks.

responses and respx answer requests instantly, so a test of how code handles a slow server, or a timeout, has nothing to exercise. This package wraps a mock’s callback so that it answers as a server which takes a given number of seconds would. A request whose read timeout is shorter than the delay waits for the timeout and then raises the same exception which the client library raises against a real slow server. Any other request gets the response after waiting for the delay.

The waiting is done by a function which you can replace, so a test can record the waits, or advance a fake clock, instead of really sleeping.

Installation

Install the extra for the client library which the code under test uses:

pip install 'mock-response-delay[requests]'
pip install 'mock-response-delay[httpx]'
pip install 'mock-response-delay[httpx2]'

This requires Python 3.12+.

Usage

requests with responses

Wrap a callback before giving it to responses. A request with a read timeout shorter than the delay raises requests.exceptions.Timeout:

"""Time out against a slow server."""

import pytest
import requests
import responses
from requests import PreparedRequest

from mock_response_delay.for_requests import delayed_responses_callback


def slow_callback(request: PreparedRequest) -> tuple[int, dict[str, str], str]:
    """Answer any request."""
    del request
    return (200, {}, "Hello")


waits: list[float] = []

with responses.RequestsMock() as mock:
    mock.add_callback(
        method="GET",
        url="https://example.com/",
        callback=delayed_responses_callback(
            callback=slow_callback,
            delay_seconds=5.0,
            sleep_fn=waits.append,
        ),
    )

    with pytest.raises(expected_exception=requests.exceptions.Timeout):
        requests.get(url="https://example.com/", timeout=1.0)

    response = requests.get(url="https://example.com/", timeout=10.0)

assert response.text == "Hello"
assert waits == [1.0, 5.0]

requests accepts the timeout as one number, or as a (connect, read) tuple. A slow server only affects the read leg, so only the read timeout is compared with the delay.

httpx with respx or httpx.MockTransport

Wrap a handler before giving it to httpx.MockTransport, or to respx as a side effect. A request with a read timeout shorter than the delay raises httpx.ReadTimeout:

"""Time out against a slow server."""

import httpx
import pytest

from mock_response_delay.for_httpx import delayed_httpx_handler


def slow_handler(request: httpx.Request) -> httpx.Response:
    """Answer any request."""
    del request
    return httpx.Response(status_code=200, text="Hello")


waits: list[float] = []
transport = httpx.MockTransport(
    handler=delayed_httpx_handler(
        handler=slow_handler,
        delay_seconds=5.0,
        sleep_fn=waits.append,
    ),
)

with httpx.Client(transport=transport) as client:
    with pytest.raises(expected_exception=httpx.ReadTimeout):
        client.get(url="https://example.com/", timeout=1.0)

    response = client.get(url="https://example.com/", timeout=10.0)

assert response.text == "Hello"
assert waits == [1.0, 5.0]

httpx2

httpx2 has its own request, response and exception classes, so it has its own module, which works in the same way with httpx2.MockTransport:

"""Time out against a slow server."""

import httpx2
import pytest

from mock_response_delay.for_httpx2 import delayed_httpx2_handler


def slow_handler(request: httpx2.Request) -> httpx2.Response:
    """Answer any request."""
    del request
    return httpx2.Response(status_code=200, text="Hello")


waits: list[float] = []
transport = httpx2.MockTransport(
    handler=delayed_httpx2_handler(
        handler=slow_handler,
        delay_seconds=5.0,
        sleep_fn=waits.append,
    ),
)

with httpx2.Client(transport=transport) as client:
    with pytest.raises(expected_exception=httpx2.ReadTimeout):
        client.get(url="https://example.com/", timeout=1.0)

    response = client.get(url="https://example.com/", timeout=10.0)

assert response.text == "Hello"
assert waits == [1.0, 5.0]

Controlling the clock

sleep_fn defaults to time.sleep, so by default the delay is real. The examples above record the waits instead, which keeps the test instant. Something which advances a fake clock, such as a freezegun tick, works the same way.

Full documentation

See the full documentation.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mock_response_delay-2026.9.7.tar.gz (152.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mock_response_delay-2026.9.7-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file mock_response_delay-2026.9.7.tar.gz.

File metadata

  • Download URL: mock_response_delay-2026.9.7.tar.gz
  • Upload date:
  • Size: 152.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mock_response_delay-2026.9.7.tar.gz
Algorithm Hash digest
SHA256 06f74384b7eed3daf74f83a2a4821bdf699accb286d940e982326b8e6228fe64
MD5 d5a422356ba96183be660e450edae5be
BLAKE2b-256 dae4994f1f6b3efca29fac956c1f40ccb0973f093ee096fd19ca9841d62fe347

See more details on using hashes here.

Provenance

The following attestation bundles were made for mock_response_delay-2026.9.7.tar.gz:

Publisher: release.yml on adamtheturtle/mock-response-delay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mock_response_delay-2026.9.7-py3-none-any.whl.

File metadata

File hashes

Hashes for mock_response_delay-2026.9.7-py3-none-any.whl
Algorithm Hash digest
SHA256 841a414b6a433afb672d12df6e3a05a37f64f94d6742390fe4aacc5dd99e10a6
MD5 a7f32495630a8971db96eec082627712
BLAKE2b-256 e17bc9e0c7f3bc4175c1be6e1ce24194b42f4723b9d176ff04b5425dc2355dfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for mock_response_delay-2026.9.7-py3-none-any.whl:

Publisher: release.yml on adamtheturtle/mock-response-delay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2026.9.8

2 files

This release

2026.9.7 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page