CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-responses

A utility library for mocking out the requests Python library

Pending
Overview
Eval results
Files

response-types.mddocs/

Response Types

Different types of mock responses including static responses, callback-based dynamic responses, and passthrough responses for selective mocking. Response types provide flexibility in how mock responses are generated and delivered.

Capabilities

Static Response

The standard Response class for fixed, predetermined responses. This is the most common response type used for straightforward mocking scenarios.

class Response:
    def __init__(
        self,
        method,
        url,
        body="",
        json=None,
        status=200,
        headers=None,
        stream=None,
        content_type=None,
        auto_calculate_content_length=False,
        match_querystring=None,
        match=(),
        *,
        passthrough=False
    ):
        """
        Create a static mock response.

        Parameters:
        - method: HTTP method string (GET, POST, etc.)
        - url: URL pattern as string or compiled regex Pattern
        - body: Response body as string or bytes
        - json: Response body as JSON object (mutually exclusive with body)
        - status: HTTP status code (default: 200)
        - headers: Response headers as dict or list of tuples
        - stream: Deprecated, use stream parameter in request instead
        - content_type: Content-Type header value (auto-detected if not specified)
        - auto_calculate_content_length: Auto-add Content-Length header
        - match_querystring: Deprecated, use query matchers instead
        - match: List of matcher functions for advanced request matching
        - passthrough: Whether to pass request to real server after matching
        """

Usage Example:

# Direct Response object creation
response_obj = responses.Response(
    method="GET",
    url="http://api.example.com/data",
    json={"message": "Hello, World!"},
    status=200,
    headers={"X-Custom-Header": "value"}
)

responses.add(response_obj)

# Or using the shortcut (more common)
responses.add(
    responses.GET,
    "http://api.example.com/data",
    json={"message": "Hello, World!"},
    status=200,
    headers={"X-Custom-Header": "value"}
)

Callback Response

Dynamic responses generated by callback functions. Useful when response content needs to be computed based on the request or when simulating complex server behavior.

class CallbackResponse:
    def __init__(
        self,
        method,
        url,
        callback,
        stream=None,
        content_type="text/plain",
        match_querystring=None,
        match=(),
        *,
        passthrough=False
    ):
        """
        Create a callback-based dynamic response.

        Parameters:
        - method: HTTP method string
        - url: URL pattern as string or regex Pattern
        - callback: Function that generates response (see callback signature below)
        - stream: Deprecated, use stream parameter in request instead
        - content_type: Default content type for callback responses
        - match_querystring: Deprecated, use query matchers instead
        - match: List of matcher functions
        - passthrough: Whether to pass request to real server after callback
        """

def add_callback(method, url, callback, match_querystring=False, content_type="text/plain", match=()):
    """
    Convenience method to add a callback response.

    Parameters:
    - method: HTTP method string
    - url: URL pattern
    - callback: Response generation function
    - match_querystring: Deprecated, use query matchers instead
    - content_type: Default content type
    - match: List of matcher functions

    Returns:
    BaseResponse object representing the callback response
    """

Callback Function Signature

def callback_function(request):
    """
    Generate dynamic response based on request.

    Parameters:
    - request: PreparedRequest object containing request details

    Returns:
    Tuple of (status_code, headers, body) or Exception to raise

    The callback can:
    - Return (int, dict, str/bytes) for normal responses
    - Return (int, list, str/bytes) where list contains (name, value) header tuples
    - Return an Exception to simulate request failures
    - Access request.url, request.method, request.body, request.headers, etc.
    """

Usage Example:

def dynamic_response_callback(request):
    # Extract data from request
    if "error" in request.url:
        return (500, {}, "Server Error")
    
    # Generate response based on request
    request_data = json.loads(request.body) if request.body else {}
    response_data = {
        "received": request_data,
        "method": request.method,
        "url": request.url
    }
    
    return (200, {"Content-Type": "application/json"}, json.dumps(response_data))

@responses.activate
def test_callback_response():
    responses.add_callback(
        responses.POST,
        "http://api.example.com/echo",
        callback=dynamic_response_callback
    )
    
    response = requests.post(
        "http://api.example.com/echo",
        json={"message": "Hello"}
    )
    
    data = response.json()
    assert data["received"]["message"] == "Hello"
    assert data["method"] == "POST"

Passthrough Response

Responses that allow requests to pass through to real servers. Useful for selective mocking where only some endpoints need to be mocked while others hit real services.

class PassthroughResponse:
    def __init__(self, *args, **kwargs):
        """
        Create a response that passes requests through to real servers.
        
        Inherits from BaseResponse with passthrough=True set automatically.
        """

def add_passthru(prefix):
    """
    Register a URL prefix or regex pattern for passthrough.

    Parameters:
    - prefix: URL prefix string or compiled regex Pattern

    All requests matching this prefix will be passed to real servers
    instead of being intercepted by responses.
    """

Usage Example:

@responses.activate
def test_selective_mocking():
    # Mock specific endpoint
    responses.add(
        responses.GET,
        "http://api.example.com/mock-me",
        json={"mocked": True}
    )
    
    # Allow real requests to this domain
    responses.add_passthru("http://httpbin.org")
    
    # This hits the mock
    mock_response = requests.get("http://api.example.com/mock-me")
    assert mock_response.json()["mocked"] is True
    
    # This hits the real server (if network available)
    real_response = requests.get("http://httpbin.org/get")
    # Would get real response from httpbin.org

Base Response Class

The abstract base class that all response types inherit from. Generally not used directly but provides the interface for custom response types.

class BaseResponse:
    def __init__(
        self,
        method,
        url,
        match_querystring=None,
        match=(),
        *,
        passthrough=False
    ):
        """
        Base class for all response types.

        Parameters:
        - method: HTTP method string
        - url: URL pattern
        - match_querystring: Deprecated query string matching
        - match: List of matcher functions
        - passthrough: Whether to pass requests through to real server
        """
    
    def matches(self, request):
        """
        Check if this response matches the given request.

        Parameters:
        - request: PreparedRequest object

        Returns:
        Tuple of (bool, str) indicating match status and reason
        """
    
    def get_response(self, request):
        """
        Generate HTTPResponse object for the request.
        
        Abstract method that must be implemented by subclasses.

        Parameters:
        - request: PreparedRequest object

        Returns:
        HTTPResponse object
        """
    
    @property
    def call_count(self):
        """Number of times this response has been used."""
    
    @property
    def calls(self):
        """CallList of requests that matched this response."""

Response Properties and Methods

All response types share common properties for tracking usage and managing state.

Call Tracking

# Properties available on all response objects
@property
def call_count():
    """
    Number of times this response has been matched and used.
    
    Returns:
    int: Count of matching requests
    """

@property
def calls():
    """
    CallList containing all requests that matched this response.
    
    Returns:
    CallList: Collection of Call objects with request/response pairs
    """

URL and Method Properties

# Properties set during response creation
url: Union[str, Pattern]  # URL pattern for matching
method: str              # HTTP method
passthrough: bool        # Whether to pass through to real server

Usage Example:

@responses.activate
def test_response_tracking():
    # Add a response
    mock_response = responses.add(
        responses.GET,
        "http://api.example.com/test",
        json={"test": True}
    )
    
    # Make requests
    requests.get("http://api.example.com/test")
    requests.get("http://api.example.com/test")
    
    # Check response usage
    assert mock_response.call_count == 2
    assert len(mock_response.calls) == 2
    
    # Access individual calls
    first_call = mock_response.calls[0]
    assert first_call.request.method == "GET"
    assert first_call.request.url == "http://api.example.com/test"

Error Handling in Callbacks

Callback responses can simulate various error conditions by returning exceptions or error status codes.

Usage Example:

from requests.exceptions import ConnectionError, Timeout

def error_callback(request):
    if "timeout" in request.url:
        # Simulate timeout
        raise Timeout("Request timed out")
    elif "connection" in request.url:
        # Simulate connection error
        raise ConnectionError("Connection failed")
    elif "server-error" in request.url:
        # Return server error
        return (500, {}, "Internal Server Error")
    else:
        return (200, {}, "OK")

@responses.activate
def test_error_handling():
    responses.add_callback(
        responses.GET,
        re.compile(r"http://api\.example\.com/.*"),
        callback=error_callback
    )
    
    # Test timeout simulation
    with pytest.raises(Timeout):
        requests.get("http://api.example.com/timeout")
    
    # Test connection error simulation
    with pytest.raises(ConnectionError):
        requests.get("http://api.example.com/connection")
    
    # Test server error
    response = requests.get("http://api.example.com/server-error")
    assert response.status_code == 500

Install with Tessl CLI

npx tessl i tessl/pypi-responses

docs

basic-mocking.md

index.md

matchers.md

recording.md

registries.md

requests-mock.md

response-types.md

tile.json