A utility library for mocking out the requests Python library
—
Advanced request matching capabilities for precise control over which requests are intercepted. Matchers allow you to specify conditions beyond URL and HTTP method, enabling detailed request validation for complex testing scenarios.
Match requests based on JSON body content with support for exact matching or partial matching for flexible test scenarios.
def json_params_matcher(params, *, strict_match=True):
"""
Match JSON payload in request body.
Parameters:
- params: dict or list representing expected JSON content
- strict_match: bool, if True validates all keys match (default: True)
if False, allows additional keys in request
Returns:
Matcher function that validates request JSON payload
Usage:
Match exact JSON:
>>> matcher = json_params_matcher({"key": "value"})
Match partial JSON (allows extra keys):
>>> matcher = json_params_matcher({"key": "value"}, strict_match=False)
"""Usage Example:
from responses.matchers import json_params_matcher
@responses.activate
def test_json_matching():
responses.add(
responses.POST,
"http://api.example.com/users",
match=[json_params_matcher({"name": "John", "age": 30})],
json={"id": 1, "name": "John", "age": 30},
status=201
)
# This will match
response = requests.post(
"http://api.example.com/users",
json={"name": "John", "age": 30}
)
assert response.status_code == 201Match requests based on URL query parameters with support for exact or partial matching.
def query_param_matcher(params, *, strict_match=True):
"""
Match query parameters in request URL.
Parameters:
- params: dict of expected query parameters
- strict_match: bool, if True validates all parameters match (default: True)
if False, allows additional parameters in request
Returns:
Matcher function that validates request query parameters
Note: Numeric values are automatically converted to strings for comparison
"""Usage Example:
from responses.matchers import query_param_matcher
@responses.activate
def test_query_matching():
responses.add(
responses.GET,
"http://api.example.com/search",
match=[query_param_matcher({"q": "python", "limit": "10"})],
json={"results": ["result1", "result2"]}
)
# This will match
response = requests.get("http://api.example.com/search?q=python&limit=10")
assert response.status_code == 200Match requests based on HTTP headers with support for exact values or regex patterns.
def header_matcher(headers, strict_match=False):
"""
Match HTTP headers in request.
Parameters:
- headers: dict of header name to expected value or regex Pattern
- strict_match: bool, if True request must have exactly these headers
if False, allows additional headers (default: False)
Returns:
Matcher function that validates request headers
Note: Standard headers added by requests library are ignored unless strict_match=True
"""Usage Example:
from responses.matchers import header_matcher
import re
@responses.activate
def test_header_matching():
responses.add(
responses.POST,
"http://api.example.com/data",
match=[header_matcher({
"Authorization": "Bearer token123",
"User-Agent": re.compile(r"MyApp/\d+\.\d+")
})],
json={"success": True}
)
# This will match
response = requests.post(
"http://api.example.com/data",
headers={
"Authorization": "Bearer token123",
"User-Agent": "MyApp/1.0"
}
)
assert response.json()["success"] is TrueMatch requests based on exact body content for non-JSON payloads.
def body_matcher(params, *, allow_blank=False):
"""
Match exact request body content.
Parameters:
- params: str representing expected body content
- allow_blank: bool, whether to allow blank/empty body content
Returns:
Matcher function that validates request body content
"""Match requests with URL-encoded form data (application/x-www-form-urlencoded).
def urlencoded_params_matcher(params, *, allow_blank=False):
"""
Match URL-encoded form data in request body.
Parameters:
- params: dict of expected form data
- allow_blank: bool, whether to allow blank values in form data
Returns:
Matcher function that validates form data content
"""Usage Example:
from responses.matchers import urlencoded_params_matcher
@responses.activate
def test_form_data_matching():
responses.add(
responses.POST,
"http://api.example.com/form",
match=[urlencoded_params_matcher({"username": "john", "password": "secret"})],
json={"login": "success"}
)
# This will match
response = requests.post(
"http://api.example.com/form",
data={"username": "john", "password": "secret"}
)
assert response.json()["login"] == "success"Match the exact query string portion of the URL.
def query_string_matcher(query):
"""
Match exact query string in request URL.
Parameters:
- query: str representing expected query string (without '?')
Returns:
Matcher function that validates query string
Note: Parameters are sorted before comparison for consistent matching
"""Match additional request parameters like timeout, verify, etc.
def request_kwargs_matcher(kwargs):
"""
Match keyword arguments passed to the request function.
Parameters:
- kwargs: dict of expected keyword arguments
Returns:
Matcher function that validates request kwargs
Common kwargs: timeout, verify, cert, proxies, stream, allow_redirects
"""Match requests with multipart/form-data content type, typically used for file uploads.
def multipart_matcher(files, data=None):
"""
Match multipart/form-data requests.
Parameters:
- files: dict of file data (same format as requests files parameter)
- data: dict of additional form fields (optional)
Returns:
Matcher function that validates multipart content
Raises:
TypeError if files parameter is empty
"""Usage Example:
from responses.matchers import multipart_matcher
@responses.activate
def test_file_upload():
responses.add(
responses.POST,
"http://api.example.com/upload",
match=[multipart_matcher(
files={"file": ("test.txt", "file content", "text/plain")},
data={"description": "Test file"}
)],
json={"uploaded": True}
)
# This will match
with open("test.txt", "w") as f:
f.write("file content")
with open("test.txt", "rb") as f:
response = requests.post(
"http://api.example.com/upload",
files={"file": ("test.txt", f, "text/plain")},
data={"description": "Test file"}
)
assert response.json()["uploaded"] is TrueMatch URL fragment identifiers (the part after '#' in URLs).
def fragment_identifier_matcher(identifier):
"""
Match URL fragment identifier.
Parameters:
- identifier: str representing expected fragment (without '#')
Returns:
Matcher function that validates URL fragment
"""Multiple matchers can be combined to create complex matching conditions. All matchers in the list must pass for the request to match.
Usage Example:
from responses.matchers import json_params_matcher, header_matcher, query_param_matcher
@responses.activate
def test_combined_matching():
responses.add(
responses.POST,
"http://api.example.com/complex",
match=[
json_params_matcher({"action": "create"}),
header_matcher({"Authorization": "Bearer token"}),
query_param_matcher({"version": "v1"})
],
json={"result": "success"}
)
# All matchers must pass
response = requests.post(
"http://api.example.com/complex?version=v1",
json={"action": "create"},
headers={"Authorization": "Bearer token"}
)
assert response.json()["result"] == "success"Install with Tessl CLI
npx tessl i tessl/pypi-responses