Automatically mock your HTTP interactions to simplify and speed up testing
Central configuration and context management for HTTP recording and playback. The VCR class provides extensive customization options for controlling recording behavior, request/response filtering, and cassette management.
The main configuration class that manages all VCR behavior including recording modes, filtering, matching, and cassette persistence.
class VCR:
"""
Main VCR configuration class for HTTP recording and playback.
Args:
path_transformer (callable, optional): Function to transform cassette file paths
before_record_request (callable, optional): Function to filter/modify requests before recording
custom_patches (tuple, optional): Additional HTTP library patches beyond default ones
filter_query_parameters (tuple, optional): Query parameter names to filter out of recordings
ignore_hosts (tuple, optional): Host names to ignore during recording (won't be recorded/matched)
record_mode (RecordMode, optional): When to record interactions (default: RecordMode.ONCE)
ignore_localhost (bool, optional): Whether to ignore localhost requests (default: False)
filter_headers (tuple, optional): Header names to filter out of recordings
before_record_response (callable, optional): Function to filter/modify responses before recording
filter_post_data_parameters (tuple, optional): POST data parameter names to filter out
match_on (tuple, optional): Request matching criteria (default: method,scheme,host,port,path,query)
before_record (callable, optional): Legacy parameter, use before_record_request instead
inject_cassette (bool, optional): Whether to inject cassette object into decorated functions
serializer (str, optional): Serialization format - "yaml" or "json" (default: "yaml")
cassette_library_dir (str, optional): Base directory for cassette files
func_path_generator (callable, optional): Function to generate cassette paths from function objects
decode_compressed_response (bool, optional): Whether to decode compressed response content
record_on_exception (bool, optional): Whether to record interactions that raise exceptions
"""
def __init__(
self,
path_transformer=None,
before_record_request=None,
custom_patches=(),
filter_query_parameters=(),
ignore_hosts=(),
record_mode=RecordMode.ONCE,
ignore_localhost=False,
filter_headers=(),
before_record_response=None,
filter_post_data_parameters=(),
match_on=("method", "scheme", "host", "port", "path", "query"),
before_record=None,
inject_cassette=False,
serializer="yaml",
cassette_library_dir=None,
func_path_generator=None,
decode_compressed_response=False,
record_on_exception=True,
): ...The primary interface for using VCR to record and replay HTTP interactions.
def use_cassette(self, path=None, **kwargs):
"""
Context manager and decorator for HTTP recording/playback.
Args:
path (str or Path, optional): Cassette file path. If None, auto-generated from function name
**kwargs: Override any VCR configuration parameters for this cassette
Returns:
Context manager that can also be used as a decorator
Usage:
# As decorator
@my_vcr.use_cassette('test.yaml')
def test_function():
# HTTP requests here will be recorded/replayed
# As context manager
with my_vcr.use_cassette('test.yaml'):
# HTTP requests here will be recorded/replayed
"""Methods for getting merged configuration and managing VCR settings.
def get_merged_config(self, **kwargs) -> dict:
"""
Get configuration with parameter overrides merged in.
Args:
**kwargs: Configuration overrides
Returns:
dict: Complete configuration for cassette creation
"""Methods for registering custom serializers, matchers, and persisters.
def register_serializer(self, name: str, serializer) -> None:
"""
Register a custom serializer for cassette persistence.
Args:
name: Serializer name for reference in configuration
serializer: Module with serialize() and deserialize() functions
"""
def register_matcher(self, name: str, matcher: callable) -> None:
"""
Register a custom request matcher function.
Args:
name: Matcher name for reference in match_on configuration
matcher: Function taking (request1, request2) that raises AssertionError if no match
"""
def register_persister(self, persister) -> None:
"""
Register a custom cassette persister (singleton replacement).
Args:
persister: Persister class with appropriate interface
"""Utility for generating test case metaclasses with automatic VCR decoration.
def test_case(self, predicate=None):
"""
Generate a metaclass that automatically decorates test methods with use_cassette.
Args:
predicate (callable, optional): Function to determine if a method should be decorated
(default: methods starting with 'test')
Returns:
Metaclass for automatic test method decoration
"""Static utility methods for path and test method handling.
@staticmethod
def is_test_method(method_name: str, function) -> bool:
"""
Determine if a method should be treated as a test method.
Args:
method_name: Name of the method
function: Function object
Returns:
bool: True if method should be decorated
"""
@staticmethod
def ensure_suffix(suffix: str) -> callable:
"""
Create a function that ensures file paths have the specified suffix.
Args:
suffix: File extension/suffix to ensure
Returns:
callable: Function that adds suffix if missing
"""# Pre-configured default VCR instance
default_vcr: VCR
# Convenience function using default instance
def use_cassette(path=None, **kwargs):
"""
Use cassette with the default VCR configuration.
This is equivalent to default_vcr.use_cassette(path, **kwargs)
"""import vcr
# Use default configuration
@vcr.use_cassette('my_cassette.yaml')
def test_basic():
# HTTP requests recorded/replayed
pass
# Custom configuration
my_vcr = vcr.VCR(
record_mode=vcr.mode.NEW_EPISODES,
serializer='json',
filter_headers=['authorization', 'x-api-key'],
ignore_hosts=['metrics.example.com']
)
@my_vcr.use_cassette('custom.json')
def test_custom():
passdef my_request_filter(request):
# Remove sensitive query parameters
if 'api_key' in request.uri:
# Custom logic to sanitize request
pass
return request
def my_response_filter(response):
# Remove sensitive response data
return response
my_vcr = vcr.VCR(
before_record_request=my_request_filter,
before_record_response=my_response_filter,
filter_query_parameters=['api_key', 'session_id'],
filter_post_data_parameters=['password', 'secret']
)def custom_matcher(r1, r2):
# Custom matching logic
if r1.path != r2.path:
raise AssertionError("Paths don't match")
my_vcr = vcr.VCR(
match_on=['method', 'scheme', 'host', 'custom_matcher']
)
my_vcr.register_matcher('custom_matcher', custom_matcher)Install with Tessl CLI
npx tessl i tessl/pypi-vcrpy