responses
Mock library for the requests Python library — intercepts HTTP calls and returns predefined responses. responses features: @responses.activate decorator, responses.add() for registering mock responses, match_querystring for URL query matching, json= parameter for JSON responses, body parameter for raw response, status= for HTTP status codes, headers= for response headers, responses.calls for inspecting made requests, stream=True for streaming responses, passthrough for selective real requests, callback support, regex URL matching, and pytest fixture via responses.fixture.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Test-only library. No network calls in mocked context. Verify no real credentials are hardcoded in mock responses. passthrough_prefixes allows real calls to specific hosts — ensure test environment doesn't make unauthorized real API calls.
⚡ Reliability
Best When
Testing code that uses the requests library — responses is the standard mock library for requests with minimal setup.
Avoid When
httpx users (use respx), async code (use respx), VCR record/replay (use vcrpy), or when httpretty's global interception is needed.
Use Cases
- • Agent mock HTTP — import responses; import requests; @responses.activate; def test_api_call(): responses.add(responses.GET, 'https://api.example.com/users', json=[{'id': 1, 'name': 'Alice'}], status=200); result = get_users(); assert len(result) == 1; assert result[0]['name'] == 'Alice' — mock; agent tests code using requests without real HTTP calls
- • Agent mock error response — @responses.activate; def test_api_error(): responses.add(responses.POST, 'https://api.example.com/data', json={'error': 'Not Found'}, status=404); with pytest.raises(HTTPError): api_client.create_item({'name': 'test'}) — error; agent tests error handling by returning HTTP error codes
- • Agent verify calls made — @responses.activate; def test_call_made(): responses.add(responses.GET, 'https://api.example.com/data', json={}); my_function(); assert len(responses.calls) == 1; assert responses.calls[0].request.url == 'https://api.example.com/data' — verify; agent asserts that specific HTTP calls were made with correct URLs
- • Agent mock with callback — def request_callback(request): payload = json.loads(request.body); return (200, {}, json.dumps({'echo': payload})); responses.add_callback(responses.POST, url, callback=request_callback) — dynamic; agent generates dynamic responses based on request content; callback receives PreparedRequest and returns (status, headers, body)
- • Agent regex URL matching — responses.add(responses.GET, re.compile(r'https://api\.example\.com/users/\d+'), json={'id': 1}); requests.get('https://api.example.com/users/42') — matches; agent mocks URL patterns; useful for dynamic IDs in paths; re.compile() for regex patterns
Not For
- • Non-requests HTTP libraries — responses only intercepts requests library; for httpx use respx; for urllib use responses.passthrough or unittest.mock
- • Async requests — responses works with synchronous requests; for async httpx use respx
- • Full network recording/replay — for VCR-style record and replay use vcrpy
Interface
Authentication
No auth — test mocking library.
Pricing
responses is Apache 2.0 licensed. Created by Sentry team. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ Unregistered URLs raise ConnectionError — with @responses.activate, any URL not added via responses.add() raises ConnectionError: 'Connection refused by Responses'; agent code: add all expected URLs before calling code under test; use assert_all_requests_are_fired=True to verify all mocks were called
- ⚠ @responses.activate intercepts requests only — code using httpx, urllib3, or aiohttp is NOT intercepted; agent code: ensure code under test uses requests library; for httpx code: use respx; for mixed: consider integration tests with real server
- ⚠ responses.add() order matters for same URL — multiple responses.add() for same URL are returned in order (queue); after all queued responses used, ConnectionError raised; agent code for repeated calls: add responses for each expected call; or use responses.add(... match_querystring=False) for catch-all
- ⚠ match_querystring defaults to False — responses.add(GET, 'http://api.com/data?page=1') with match_querystring=False (default) matches any URL with that path regardless of query string; agent code needing query string matching: use match=[matchers.query_param_matcher({'page': '1'})] — newer API; or match_querystring=True in older API
- ⚠ json= sets Content-Type automatically — responses.add(... json={'key': 'val'}) sets Content-Type: application/json and serializes dict; using body=json.dumps(data) does NOT set Content-Type automatically; agent code: use json= parameter for JSON responses; body= for raw string/bytes
- ⚠ responses.calls contains all calls — responses.calls is a list of Call objects; responses.calls[0].request is PreparedRequest; responses.calls[0].response is Response; agent code asserting call count: assert len(responses.calls) == 2; asserting body: assert json.loads(responses.calls[0].request.body) == expected_payload
Alternatives
Full Evaluation Report
Comprehensive deep-dive: security analysis, reliability audit, agent experience review, cost modeling, competitive positioning, and improvement roadmap for responses.
AI-powered analysis · PDF + markdown · Delivered within 30 minutes
Package Brief
Quick verdict, integration guide, cost projections, gotchas with workarounds, and alternatives comparison.
Delivered within 10 minutes
Score Monitoring
Get alerted when this package's AF, security, or reliability scores change significantly. Stay ahead of regressions.
Continuous monitoring
Scores are editorial opinions as of 2026-03-06.