0
# VCR.py
1
2
A Python library that records HTTP interactions during test execution and replays them in subsequent runs, enabling completely offline, deterministic, and fast tests. VCR.py automatically intercepts HTTP requests and responses through supported libraries and serializes them to cassette files, eliminating actual network traffic while maintaining test reliability.
3
4
## Package Information
5
6
- **Package Name**: vcrpy
7
- **Package Type**: library
8
- **Language**: Python
9
- **Installation**: `pip install vcrpy`
10
11
## Core Imports
12
13
```python
14
import vcr
15
```
16
17
Common patterns:
18
19
```python
20
# Use default VCR instance
21
from vcr import use_cassette
22
23
# Create custom VCR instance
24
from vcr import VCR
25
26
# Access record modes
27
from vcr import mode # or vcr.mode
28
29
# For unittest integration
30
from vcr.unittest import VCRTestCase, VCRMixin
31
```
32
33
## Basic Usage
34
35
```python
36
import vcr
37
import requests
38
39
# Using decorator
40
@vcr.use_cassette('fixtures/vcr_cassettes/synopsis.yaml')
41
def test_synopsis():
42
response = requests.get('http://httpbin.org/json')
43
assert response.status_code == 200
44
45
# Using context manager
46
def test_with_context():
47
with vcr.use_cassette('fixtures/vcr_cassettes/synopsis.yaml'):
48
response = requests.get('http://httpbin.org/json')
49
assert response.status_code == 200
50
51
# Custom VCR configuration
52
my_vcr = vcr.VCR(
53
serializer='json',
54
record_mode='once',
55
filter_headers=['authorization'],
56
match_on=['method', 'scheme', 'host', 'port', 'path', 'query']
57
)
58
59
@my_vcr.use_cassette('custom_cassette.json')
60
def test_with_custom_vcr():
61
response = requests.get('http://api.example.com/data')
62
assert response.status_code == 200
63
```
64
65
## Architecture
66
67
VCR.py operates through HTTP library patching and cassette-based recording:
68
69
- **VCR Configuration**: Central configuration class managing recording behavior, filtering, and matching
70
- **Cassettes**: Files containing recorded HTTP interactions with request/response pairs
71
- **Request Matchers**: Configurable functions determining how requests are matched for playback
72
- **Filters**: Functions for modifying or removing sensitive data before recording
73
- **Stubs**: HTTP library patches for interception (requests, urllib3, httplib2, httpx, aiohttp, boto3, tornado)
74
75
The library supports multiple record modes, serialization formats, and extensive customization options for different testing scenarios.
76
77
## Capabilities
78
79
### Core VCR Configuration
80
81
Central configuration and context management for HTTP recording and playback, including cassette management, record modes, and extensive customization options.
82
83
```python { .api }
84
class VCR:
85
def __init__(
86
self,
87
path_transformer=None,
88
before_record_request=None,
89
custom_patches=(),
90
filter_query_parameters=(),
91
ignore_hosts=(),
92
record_mode=RecordMode.ONCE,
93
ignore_localhost=False,
94
filter_headers=(),
95
before_record_response=None,
96
filter_post_data_parameters=(),
97
match_on=("method", "scheme", "host", "port", "path", "query"),
98
before_record=None,
99
inject_cassette=False,
100
serializer="yaml",
101
cassette_library_dir=None,
102
func_path_generator=None,
103
decode_compressed_response=False,
104
record_on_exception=True,
105
): ...
106
107
def use_cassette(self, path=None, **kwargs): ...
108
109
def use_cassette(path=None, **kwargs): ...
110
```
111
112
[Core VCR Configuration](./core-configuration.md)
113
114
### Record Modes and Control
115
116
Recording behavior configuration that determines when HTTP interactions are recorded versus replayed from existing cassettes.
117
118
```python { .api }
119
class RecordMode(str, Enum):
120
ALL = "all"
121
ANY = "any"
122
NEW_EPISODES = "new_episodes"
123
NONE = "none"
124
ONCE = "once"
125
126
# Alias for RecordMode
127
mode = RecordMode
128
```
129
130
[Record Modes](./record-modes.md)
131
132
### Request and Response Processing
133
134
HTTP request and response representation with case-insensitive headers, body processing, and URI parsing capabilities.
135
136
```python { .api }
137
class Request:
138
def __init__(self, method: str, uri: str, body, headers): ...
139
140
@property
141
def headers(self) -> HeadersDict: ...
142
@property
143
def body(self): ...
144
@property
145
def method(self) -> str: ...
146
@property
147
def uri(self) -> str: ...
148
@property
149
def scheme(self) -> str: ...
150
@property
151
def host(self) -> str: ...
152
@property
153
def port(self) -> int: ...
154
@property
155
def path(self) -> str: ...
156
@property
157
def query(self) -> str: ...
158
159
class HeadersDict(dict):
160
"""Case-insensitive dictionary for HTTP headers"""
161
```
162
163
[Request and Response Processing](./request-response.md)
164
165
### Request Matching
166
167
Functions for determining if recorded requests match incoming requests, supporting multiple matching strategies for different use cases.
168
169
```python { .api }
170
def method(r1: Request, r2: Request): ...
171
def uri(r1: Request, r2: Request): ...
172
def host(r1: Request, r2: Request): ...
173
def scheme(r1: Request, r2: Request): ...
174
def port(r1: Request, r2: Request): ...
175
def path(r1: Request, r2: Request): ...
176
def query(r1: Request, r2: Request): ...
177
def headers(r1: Request, r2: Request): ...
178
def raw_body(r1: Request, r2: Request): ...
179
def body(r1: Request, r2: Request): ...
180
181
def requests_match(r1: Request, r2: Request, matchers): ...
182
def get_matchers_results(r1: Request, r2: Request, matchers): ...
183
```
184
185
[Request Matching](./request-matching.md)
186
187
### Data Filtering
188
189
Functions for removing or replacing sensitive data in requests and responses before recording to cassettes.
190
191
```python { .api }
192
def replace_headers(request: Request, replacements: list): ...
193
def remove_headers(request: Request, headers_to_remove: list): ...
194
def replace_query_parameters(request: Request, replacements: list): ...
195
def replace_post_data_parameters(request: Request, replacements: list): ...
196
def decode_response(response): ...
197
```
198
199
[Data Filtering](./data-filtering.md)
200
201
### Test Framework Integration
202
203
Integration classes for unittest framework providing automatic cassette management and VCR configuration for test cases.
204
205
```python { .api }
206
class VCRMixin:
207
vcr_enabled: bool = True
208
def setUp(self): ...
209
def _get_vcr(self, **kwargs) -> VCR: ...
210
def _get_vcr_kwargs(self, **kwargs) -> dict: ...
211
def _get_cassette_library_dir(self) -> str: ...
212
def _get_cassette_name(self) -> str: ...
213
214
class VCRTestCase(VCRMixin, unittest.TestCase):
215
pass
216
```
217
218
[Test Framework Integration](./test-integration.md)
219
220
### Error Handling
221
222
Exception classes for handling VCR-specific errors during recording and playback operations.
223
224
```python { .api }
225
class CannotOverwriteExistingCassetteException(Exception):
226
def __init__(self, cassette, failed_request): ...
227
cassette: Cassette
228
failed_request: Request
229
230
class UnhandledHTTPRequestError(KeyError):
231
"""Raised when a cassette does not contain the request we want."""
232
```
233
234
[Error Handling](./error-handling.md)
235
236
### Serialization
237
238
Cassette serialization and deserialization support for YAML and JSON formats with extensible serializer registration.
239
240
```python { .api }
241
# YAML Serializer
242
def deserialize(cassette_string: str) -> dict: ...
243
def serialize(cassette_dict: dict) -> str: ...
244
245
# JSON Serializer
246
def deserialize(cassette_string: str) -> dict: ...
247
def serialize(cassette_dict: dict) -> str: ...
248
```
249
250
[Serialization](./serialization.md)
251
252
## Types
253
254
```python { .api }
255
from typing import Callable, Any, Optional, Union, Dict, List, Tuple
256
from enum import Enum
257
from pathlib import Path
258
259
# Configuration types
260
PathTransformer = Callable[[str], str]
261
FilterFunction = Callable[[Any], Any]
262
MatcherFunction = Callable[[Request, Request], None] # Raises AssertionError if no match
263
SerializerModule = Any # Module with serialize/deserialize functions
264
265
# Request/Response types
266
Headers = Union[Dict[str, str], HeadersDict]
267
Body = Union[str, bytes, Any] # file-like objects or iterables also supported
268
```