0
# HTTPMock
1
2
A mocking library for Python's `requests` library that enables testing applications without making actual HTTP calls. HTTPMock provides decorators and context managers to intercept and mock HTTP requests with flexible response control.
3
4
## Package Information
5
6
- **Package Name**: httmock
7
- **Language**: Python
8
- **Installation**: `pip install httmock`
9
- **Dependencies**: requests >= 1.0.0
10
11
## Core Imports
12
13
```python
14
from httmock import HTTMock, urlmatch, all_requests, with_httmock, response
15
```
16
17
Import specific decorators and utilities:
18
19
```python
20
from httmock import remember_called, text_type, binary_type
21
```
22
23
## Basic Usage
24
25
```python
26
from httmock import urlmatch, HTTMock
27
import requests
28
29
# Create a URL-matching mock handler
30
@urlmatch(netloc=r'(.*\.)?google\.com$')
31
def google_mock(url, request):
32
return 'Feeling lucky, punk?'
33
34
# Use context manager to mock requests
35
with HTTMock(google_mock):
36
r = requests.get('http://google.com/')
37
print(r.content) # b'Feeling lucky, punk?'
38
```
39
40
Alternative decorator usage:
41
42
```python
43
from httmock import with_httmock, all_requests
44
import requests
45
46
@all_requests
47
def response_content(url, request):
48
return {'status_code': 200, 'content': 'Oh hai'}
49
50
@with_httmock(response_content)
51
def test_function():
52
r = requests.get('https://example.com/')
53
print(r.status_code) # 200
54
print(r.content) # b'Oh hai'
55
56
test_function()
57
```
58
59
## Architecture
60
61
HTTPMock works by monkey-patching the `requests.Session.send` and `requests.Session.prepare_request` methods during the context manager's lifetime. This interceptor architecture allows:
62
63
- **Request Interception**: All HTTP requests made through the `requests` library are intercepted before they reach the network
64
- **Handler Chain**: Multiple mock handlers can be registered, with the first matching handler providing the response
65
- **Fallback Behavior**: If no handlers match a request, it falls through to make the actual HTTP call
66
- **Response Processing**: Handler responses can be strings, dictionaries, or full `requests.Response` objects, with automatic conversion
67
- **Cookie Management**: Set-Cookie headers are automatically processed and made available via `response.cookies`
68
- **Redirect Handling**: Mock responses properly integrate with requests' redirect resolution system
69
70
The context manager pattern ensures that mocking is scoped and original functionality is restored when exiting the mock context.
71
72
## Capabilities
73
74
### Context Manager (HTTMock)
75
76
Primary context manager for mocking HTTP requests within a specific scope.
77
78
```python { .api }
79
class HTTMock:
80
def __init__(self, *handlers):
81
"""
82
Initialize with mock handler functions.
83
84
Parameters:
85
- handlers: Variable number of mock handler functions
86
"""
87
88
def __enter__(self):
89
"""Enter context, patch requests.Session methods."""
90
91
def __exit__(self, exc_type, exc_val, exc_tb):
92
"""Exit context, restore original requests.Session methods."""
93
94
def intercept(self, request, **kwargs):
95
"""
96
Intercept and handle mock responses.
97
98
Parameters:
99
- request: The HTTP request object
100
- kwargs: Additional request arguments
101
102
Returns:
103
- Mock response or None for fallthrough
104
"""
105
```
106
107
### URL Matching Decorator
108
109
Decorator for conditional URL-based request matching with regex support.
110
111
```python { .api }
112
def urlmatch(scheme=None, netloc=None, path=None, method=None, query=None):
113
"""
114
Decorator for URL-based request matching.
115
116
Parameters:
117
- scheme: str, URL scheme to match (http, https, etc.)
118
- netloc: str, regex pattern for network location (domain)
119
- path: str, regex pattern for URL path
120
- method: str, HTTP method to match (GET, POST, etc.)
121
- query: str, regex pattern for query string
122
123
Returns:
124
- Decorator that wraps handler functions
125
126
Handler Function Signature:
127
- handler(url, request) -> str | dict | requests.Response | None
128
"""
129
```
130
131
### Universal Request Decorator
132
133
Decorator that matches all HTTP requests without conditions.
134
135
```python { .api }
136
def all_requests(func):
137
"""
138
Decorator that matches all HTTP requests.
139
140
Parameters:
141
- func: Handler function to decorate
142
143
Returns:
144
- Decorated handler function
145
146
Handler Function Signature:
147
- handler(url, request) -> str | dict | requests.Response | None
148
"""
149
```
150
151
### Function Decorator
152
153
Decorator that wraps functions with HTTP mocking context.
154
155
```python { .api }
156
def with_httmock(*handlers):
157
"""
158
Function decorator for HTTP mocking.
159
160
Parameters:
161
- handlers: Variable number of mock handler functions
162
163
Returns:
164
- Decorator that wraps functions with mocking context
165
"""
166
```
167
168
### Response Factory
169
170
Factory function for creating mock Response objects with full control.
171
172
```python { .api }
173
def response(status_code=200, content='', headers=None, reason=None,
174
elapsed=0, request=None, stream=False, http_vsn=11):
175
"""
176
Create a mock requests.Response object.
177
178
Parameters:
179
- status_code: int, HTTP status code (default: 200)
180
- content: str | dict | list | bytes, response content
181
- headers: dict, HTTP headers (default: None)
182
- reason: str, HTTP reason phrase (default: None)
183
- elapsed: int, elapsed time in seconds (default: 0)
184
- request: Request object to associate with response
185
- stream: bool, enable streaming response (default: False)
186
- http_vsn: int, HTTP version (10 or 11, default: 11)
187
188
Returns:
189
- requests.Response object
190
191
Notes:
192
- Dict/list content is automatically JSON-encoded
193
- String content is UTF-8 encoded
194
- Set-Cookie headers automatically populate response.cookies
195
"""
196
```
197
198
### Call Tracking Decorator
199
200
Decorator that tracks call statistics for mock handlers.
201
202
```python { .api }
203
def remember_called(func):
204
"""
205
Decorator that tracks handler call statistics.
206
207
Parameters:
208
- func: Handler function to track
209
210
Returns:
211
- Decorated function with call tracking attributes
212
213
Added Attributes:
214
- func.call['count']: int, number of times called
215
- func.call['called']: bool, whether function was called
216
- func.call['requests']: list, request objects from all calls
217
"""
218
```
219
220
### Utility Functions
221
222
Helper functions for handler management and response processing.
223
224
```python { .api }
225
def first_of(handlers, *args, **kwargs):
226
"""
227
Return first non-None result from handler list.
228
229
Parameters:
230
- handlers: Iterable of handler functions
231
- args, kwargs: Arguments to pass to handlers
232
233
Returns:
234
- First non-None handler result or None
235
"""
236
```
237
238
## Handler Function Patterns
239
240
Mock handlers accept `(url, request)` parameters and can return:
241
242
### String Response
243
```python
244
def handler(url, request):
245
return "Simple text response"
246
```
247
248
### Dictionary Response
249
```python
250
def handler(url, request):
251
return {
252
'status_code': 404,
253
'content': 'Not Found',
254
'headers': {'Content-Type': 'text/plain'},
255
'elapsed': 0.1
256
}
257
```
258
259
### Response Object
260
```python
261
def handler(url, request):
262
return response(
263
status_code=403,
264
content={'message': 'API rate limit exceeded'},
265
headers={'content-type': 'application/json'},
266
request=request
267
)
268
```
269
270
### Conditional Logic
271
```python
272
@urlmatch(netloc=r'api\.example\.com$', method='POST')
273
def api_handler(url, request):
274
if 'auth' not in request.headers:
275
return {'status_code': 401, 'content': 'Unauthorized'}
276
return {'status_code': 200, 'content': {'success': True}}
277
```
278
279
## Types
280
281
```python { .api }
282
# Type compatibility constants
283
text_type = str # Python 3: str, Python 2: unicode
284
binary_type = bytes # Python 3: bytes, Python 2: str
285
286
# Request and Response objects are from the requests library
287
# Handler functions receive:
288
# - url: urllib.parse.SplitResult (parsed URL components)
289
# - request: requests.PreparedRequest object
290
```
291
292
## Error Handling
293
294
HTTMock raises `TypeError` for unsupported response types from handlers:
295
296
```python
297
@all_requests
298
def bad_handler(url, request):
299
return 42 # Raises TypeError: "Don't know how to handle response of type <class 'int'>"
300
```
301
302
Valid response types are:
303
- `str` or `bytes`: Content-only response (status 200)
304
- `dict`: Response with status_code, content, headers, etc.
305
- `requests.Response`: Complete response object
306
- `None`: Fall through to next handler or real request