HTTP traffic mocking and expectations made easy for Python testing and development
npx @tessl/cli install tessl/pypi-pook@2.1.0Pook is a versatile HTTP mocking library for Python that provides a fluent, declarative interface for creating HTTP request/response mocks. It enables developers to intercept and mock HTTP traffic for testing and development, supporting a wide range of HTTP methods, request matching patterns, and response configurations.
pip install pookimport pookFor specific functionality:
from pook import (
# Engine control
activate, on, disable, off, reset, use, use_network,
# HTTP method functions
get, post, put, patch, delete, head, options, mock,
# Core classes
Mock, Request, Response, Engine, MatcherEngine, MockEngine,
# State inspection
pending, pending_mocks, unmatched_requests, isactive, isdone,
# Network control
enable_network, disable_network, use_network_filter,
# Utilities
regex
)Pytest integration (automatic with pytest plugin):
def test_with_pook(pook):
# pook fixture automatically available when pook is installed
passimport pook
import requests
# Activate pook HTTP interception
pook.activate()
# Create a mock for a GET request
pook.get('https://api.example.com/users/1').reply(200).json({
'id': 1,
'name': 'John Doe',
'email': 'john@example.com'
})
# Make the HTTP request - it will be intercepted by pook
response = requests.get('https://api.example.com/users/1')
print(response.json()) # {'id': 1, 'name': 'John Doe', 'email': 'john@example.com'}
# Clean up
pook.off()Using as decorator:
import pook
import requests
@pook.activate
def test_api_call():
# Mock is active only within this function
pook.get('https://api.example.com/health').reply(200).json({'status': 'ok'})
response = requests.get('https://api.example.com/health')
assert response.json()['status'] == 'ok'
test_api_call()Using with context manager:
import pook
import requests
with pook.use() as mock_engine:
# Create mocks within isolated engine
pook.post('https://api.example.com/users').reply(201).json({'id': 2})
response = requests.post('https://api.example.com/users', json={'name': 'Jane'})
assert response.status_code == 201
# Engine automatically cleaned upPook's architecture is built around three core components that work together to provide flexible HTTP mocking:
This design enables pook to integrate seamlessly with popular HTTP libraries like requests, urllib, and aiohttp while providing comprehensive mocking capabilities for testing and development workflows.
HTTP method-specific functions for creating mocks with fluent API support. These functions provide the primary interface for setting up HTTP request interceptions.
def mock(url=None, **kw):
"""
Creates and registers a new HTTP mock.
Parameters:
- url (str, optional): Request URL to mock
- activate (bool, optional): Force mock engine activation
- **kw: Additional Mock constructor arguments
Returns:
Mock: New mock instance
"""
def get(url, **kw):
"""
Registers a new mock HTTP request with GET method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def post(url, **kw):
"""
Registers a new mock HTTP request with POST method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def put(url, **kw):
"""
Registers a new mock HTTP request with PUT method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def patch(url=None, **kw):
"""
Registers a new mock HTTP request with PATCH method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def delete(url, **kw):
"""
Registers a new mock HTTP request with DELETE method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def head(url, **kw):
"""
Registers a new mock HTTP request with HEAD method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""
def options(url=None, **kw):
"""
Registers a new mock HTTP request with OPTIONS method.
Parameters:
- url (str): Request URL to mock
- **kw: Additional Mock constructor arguments
Returns:
Mock: Mock instance
"""Core classes for detailed request matching and response configuration. These classes provide the building blocks for complex mock scenarios.
class Mock:
"""
Mock is used to declare and compose HTTP request/response mock
definition and matching expectations with fluent API DSL.
"""
def __init__(self, url=None, method=None, **kw):
"""
Parameters:
- url (str): URL to match
- method (str): HTTP method name to match
- **kw: Additional configuration options
"""
class Request:
"""
Request object representing the request mock expectation DSL.
"""
def __init__(self, method="GET", url=None, headers=None, query=None, body=None, **kw):
"""
Parameters:
- method (str): HTTP method to match
- url (str): URL request to intercept and match
- headers (dict): HTTP headers to match
- query (dict): URL query params to match
- body (bytes): Request body payload to match
"""
class Response:
"""
Response is used to declare and compose HTTP mock response
fields with chainable DSL interface.
"""
def __init__(self, status=200, headers=None, body=None, **kw):
"""
Parameters:
- status (int): HTTP response status code
- headers (dict): HTTP response headers
- body (str|bytes): HTTP response body
"""Functions for controlling pook's HTTP interception engine, networking modes, and mock lifecycle management.
def activate(fn=None):
"""
Enables HTTP traffic interceptors. Can be used as a decorator.
Parameters:
- fn (function, optional): Function to decorate when used as decorator
Returns:
function: Decorator wrapper when used as decorator, None otherwise
"""
def disable():
"""
Disables HTTP traffic interceptors without flushing mocks.
"""
def reset():
"""
Resets current mock engine state, flushing all registered mocks.
"""
def engine():
"""
Returns the current running mock engine instance.
Returns:
Engine: Current engine instance
"""
def use(network=False):
"""
Creates a new isolated mock engine to be used via context manager.
Parameters:
- network (bool, optional): Enable networking mode
Returns:
Context manager yielding Engine
"""
def use_network():
"""
Creates a new isolated mock engine with networking enabled.
Returns:
Context manager yielding Engine with networking mode enabled
"""
def enable_network(*hostnames):
"""
Enables real networking mode for unmatched mocks.
Parameters:
- *hostnames (str): Optional hostnames to enable networking for
"""
def disable_network():
"""
Disables real traffic networking mode in the current mock engine.
"""
def use_network_filter(*fn):
"""
Adds network filters to determine if certain outgoing unmatched HTTP
traffic can establish real network connections.
Parameters:
- *fn (function): Variadic function filter arguments to be used
"""Functions for examining mock states, pending mocks, unmatched requests, and engine status for debugging and testing.
def pending():
"""
Returns the number of pending mocks to be matched.
Returns:
int: Number of pending mocks
"""
def pending_mocks():
"""
Returns pending mocks to be matched.
Returns:
list: List of pending mock instances
"""
def unmatched_requests():
"""
Returns a list of unmatched requests (networking mode only).
Returns:
list: List of unmatched intercepted requests
"""
def unmatched():
"""
Returns the total number of unmatched requests intercepted by pook.
Returns:
int: Total number of unmatched requests
"""
def isunmatched():
"""
Returns True if there are unmatched requests (networking mode only).
Returns:
bool: True if unmatched requests exist
"""
def isactive():
"""
Returns True if pook is active and intercepting traffic.
Returns:
bool: Current activation status
"""
def isdone():
"""
Returns True if all registered mocks have been triggered.
Returns:
bool: Completion status
"""Built-in pytest fixture for HTTP traffic mocking in test environments.
def pook():
"""
Pytest fixture for HTTP traffic mocking and testing.
Provides an isolated pook engine that automatically activates
for the test duration and cleans up afterward.
Returns:
pook module with activated engine in isolated context
"""Usage example:
import requests
def test_api_call(pook):
# pook fixture automatically provides isolated engine
pook.get('https://api.example.com/users').reply(200).json([
{'id': 1, 'name': 'John'}
])
response = requests.get('https://api.example.com/users')
assert response.status_code == 200
assert len(response.json()) == 1
# Engine automatically deactivated and cleaned upclass Engine:
"""
Engine represents the mock interceptor and matcher engine responsible
for triggering interceptors and matching outgoing HTTP traffic.
"""
def __init__(self, network=False):
"""
Parameters:
- network (bool, optional): Enables/disables real networking mode
"""
# Key attributes
debug: bool # Enables/disables debug mode
active: bool # Current engine activation status
networking: bool # Current engine networking mode status
mocks: list # Engine mocks
unmatched_reqs: list # Unmatched outgoing HTTP requests
class MatcherEngine:
"""
HTTP request matcher engine used by Mock to test if an intercepted
outgoing HTTP request should be mocked out.
"""
def add(self, matcher):
"""
Adds new matcher function to engine.
Parameters:
- matcher: Matcher function or object
"""
def match(self, request):
"""
Matches HTTP request against registered matchers.
Parameters:
- request: HTTP request to match
Returns:
tuple: (bool, list[str]) - Match result and error messages
"""
class MockEngine:
"""
Low-level HTTP traffic interceptor engine that manages interceptors
for different HTTP clients.
"""
def add_interceptor(self, *interceptors):
"""
Adds HTTP traffic interceptors.
Parameters:
- *interceptors: Interceptor instances to add
"""
def flush_interceptors(self):
"""
Flushes all registered HTTP traffic interceptors.
"""
def remove_interceptor(self, name):
"""
Removes a specific interceptor by name.
Parameters:
- name (str): Name of the interceptor to remove
"""
def activate(self):
"""
Activates all registered HTTP traffic interceptors.
"""
def disable(self):
"""
Disables all registered HTTP traffic interceptors.
"""
def regex(expression, flags=None):
"""
Convenient shortcut to re.compile() for regex compilation.
Parameters:
- expression (str): Regular expression value
- flags (int, optional): Regular expression flags
Returns:
Pattern: Compiled regular expression object
"""