0
# Request Recording
1
2
Record actual HTTP requests and responses to generate response configurations for future mocking. The recording functionality allows you to capture real network interactions and replay them in tests, making it easier to create comprehensive test suites based on actual API behavior.
3
4
## Capabilities
5
6
### Record Decorator
7
8
Decorator that records HTTP requests made during function execution and saves them to a YAML file for later use in mocking.
9
10
```python { .api }
11
from responses._recorder import record
12
13
@record(file_path="responses.yaml")
14
def function_making_requests():
15
"""
16
Decorator to record HTTP requests and responses.
17
18
Parameters:
19
- file_path: str or Path, where to save recorded responses (default: "response.yaml")
20
21
During execution, all HTTP requests are passed through to real servers
22
and the responses are recorded. The recorded data can later be used
23
to create mock responses for testing.
24
"""
25
```
26
27
**Usage Example:**
28
29
```python
30
from responses._recorder import record
31
import requests
32
33
@record(file_path="api_responses.yaml")
34
def fetch_user_data():
35
# These requests hit real servers and are recorded
36
user_response = requests.get("https://api.example.com/users/1")
37
posts_response = requests.get("https://api.example.com/users/1/posts")
38
39
return user_response.json(), posts_response.json()
40
41
# Run the function to record responses
42
user_data, posts_data = fetch_user_data()
43
44
# The file api_responses.yaml now contains the recorded responses
45
# which can be loaded later for mocking
46
```
47
48
### Recorder Class
49
50
The Recorder class provides programmatic control over request recording with customizable behavior and output options.
51
52
```python { .api }
53
class Recorder:
54
def __init__(
55
self,
56
*,
57
target="requests.adapters.HTTPAdapter.send",
58
registry=OrderedRegistry
59
):
60
"""
61
Create a Recorder instance for capturing HTTP requests.
62
63
Parameters:
64
- target: str, method path to patch for interception
65
- registry: Registry class, typically OrderedRegistry for recording
66
67
The Recorder extends RequestsMock to capture real responses
68
instead of returning mock responses.
69
"""
70
71
def record(self, *, file_path="response.yaml"):
72
"""
73
Decorator method for recording requests to a file.
74
75
Parameters:
76
- file_path: str or Path, output file for recorded responses
77
78
Returns:
79
Decorator function that records HTTP requests during execution
80
"""
81
82
def dump_to_file(
83
self,
84
file_path,
85
*,
86
registered=None
87
):
88
"""
89
Save recorded responses to a YAML file.
90
91
Parameters:
92
- file_path: str or Path, output file path
93
- registered: List of BaseResponse objects (optional, uses current registry)
94
95
Exports recorded responses in YAML format compatible with
96
the _add_from_file method for later mocking.
97
"""
98
```
99
100
**Usage Example:**
101
102
```python
103
from responses._recorder import Recorder
104
105
def test_recording():
106
recorder = Recorder()
107
108
with recorder:
109
# Make real requests
110
response = requests.get("https://api.example.com/data")
111
post_response = requests.post(
112
"https://api.example.com/submit",
113
json={"key": "value"}
114
)
115
116
# Save recorded responses
117
recorder.dump_to_file("recorded_responses.yaml")
118
119
# Later, load for mocking
120
@responses.activate
121
def test_with_recorded():
122
responses._add_from_file("recorded_responses.yaml")
123
124
# Now requests will use recorded responses instead of hitting real servers
125
mock_response = requests.get("https://api.example.com/data")
126
assert mock_response.status_code == 200
127
```
128
129
### File-Based Response Loading
130
131
Load previously recorded or manually created response configurations from YAML files.
132
133
```python { .api }
134
def _add_from_file(file_path):
135
"""
136
Load response configurations from a YAML file.
137
138
Parameters:
139
- file_path: str or Path to YAML file containing response configurations
140
141
The YAML file should follow this structure:
142
responses:
143
- response:
144
method: HTTP_METHOD
145
url: URL_PATTERN
146
body: RESPONSE_BODY
147
status: STATUS_CODE
148
headers: HEADERS_DICT
149
content_type: CONTENT_TYPE
150
auto_calculate_content_length: BOOLEAN
151
152
This function is typically used with files generated by the Recorder
153
but can also load manually created response configurations.
154
"""
155
```
156
157
**YAML File Format:**
158
159
```yaml
160
responses:
161
- response:
162
method: GET
163
url: https://api.example.com/users/1
164
body: '{"id": 1, "name": "John Doe", "email": "john@example.com"}'
165
status: 200
166
headers:
167
Content-Type: application/json
168
X-RateLimit-Remaining: "99"
169
content_type: application/json
170
auto_calculate_content_length: false
171
- response:
172
method: POST
173
url: https://api.example.com/users
174
body: '{"id": 2, "name": "Jane Smith", "email": "jane@example.com"}'
175
status: 201
176
headers:
177
Content-Type: application/json
178
Location: https://api.example.com/users/2
179
content_type: application/json
180
auto_calculate_content_length: false
181
```
182
183
**Usage Example:**
184
185
```python
186
import responses
187
188
@responses.activate
189
def test_from_file():
190
# Load recorded responses
191
responses._add_from_file("api_responses.yaml")
192
193
# Make requests that will hit the loaded mocks
194
user_response = requests.get("https://api.example.com/users/1")
195
create_response = requests.post(
196
"https://api.example.com/users",
197
json={"name": "New User", "email": "new@example.com"}
198
)
199
200
assert user_response.status_code == 200
201
assert create_response.status_code == 201
202
assert "Location" in create_response.headers
203
```
204
205
### Recording Workflow
206
207
The typical workflow for using the recording functionality:
208
209
1. **Record Phase**: Use `@record` decorator or `Recorder` class to capture real HTTP interactions
210
2. **Save Phase**: Responses are automatically saved to YAML file during recording
211
3. **Mock Phase**: Load recorded responses using `_add_from_file` for testing
212
4. **Validation Phase**: Tests run against recorded responses instead of real servers
213
214
**Complete Workflow Example:**
215
216
```python
217
from responses._recorder import record, _add_from_file
218
import responses
219
import requests
220
221
# Step 1: Record real API interactions
222
@record(file_path="integration_responses.yaml")
223
def record_integration_flow():
224
# Authenticate
225
auth_response = requests.post("https://api.example.com/auth", {
226
"username": "testuser",
227
"password": "testpass"
228
})
229
token = auth_response.json()["token"]
230
231
# Make authenticated requests
232
headers = {"Authorization": f"Bearer {token}"}
233
user_data = requests.get("https://api.example.com/profile", headers=headers)
234
235
# Update profile
236
updated_profile = requests.put(
237
"https://api.example.com/profile",
238
headers=headers,
239
json={"bio": "Updated bio"}
240
)
241
242
return user_data.json(), updated_profile.json()
243
244
# Run recording (hits real API)
245
user_profile, updated_data = record_integration_flow()
246
247
# Step 2: Use recorded responses in tests
248
@responses.activate
249
def test_integration_flow():
250
# Load recorded responses
251
responses._add_from_file("integration_responses.yaml")
252
253
# Run same flow against mocks
254
auth_response = requests.post("https://api.example.com/auth", {
255
"username": "testuser",
256
"password": "testpass"
257
})
258
259
token = auth_response.json()["token"]
260
headers = {"Authorization": f"Bearer {token}"}
261
262
profile_response = requests.get("https://api.example.com/profile", headers=headers)
263
update_response = requests.put(
264
"https://api.example.com/profile",
265
headers=headers,
266
json={"bio": "Updated bio"}
267
)
268
269
# Assertions based on recorded data
270
assert profile_response.status_code == 200
271
assert update_response.status_code == 200
272
assert "token" in auth_response.json()
273
274
# Run test (uses mocks, no network calls)
275
test_integration_flow()
276
```
277
278
## Module-Level Access
279
280
```python { .api }
281
# Global recorder instance and decorator
282
recorder: Recorder # Pre-configured Recorder instance
283
record: callable # Decorator function from global recorder instance
284
285
# File loading function
286
_add_from_file: callable # Function to load responses from YAML files
287
```