0
# Configuration
1
2
Flexible configuration system for both global bravado settings and per-request options. The configuration system supports response metadata customization, timeout configuration, callback mechanisms, and extensive behavioral controls.
3
4
## Capabilities
5
6
### BravadoConfig
7
8
Global configuration object that controls bravado's behavior across all requests. Uses a NamedTuple structure for type safety and immutability.
9
10
```python { .api }
11
class BravadoConfig:
12
also_return_response: bool
13
disable_fallback_results: bool
14
response_metadata_class: Type[BravadoResponseMetadata]
15
sensitive_headers: list
16
```
17
18
**Attributes:**
19
- `also_return_response` (bool): Whether operations should return BravadoResponse objects with metadata
20
- `disable_fallback_results` (bool): Kill switch to disable fallback results even if provided
21
- `response_metadata_class` (Type): Class to use for response metadata objects
22
- `sensitive_headers` (list): List of header names to exclude from debug logs
23
24
### RequestConfig
25
26
Per-request configuration that allows fine-grained control over individual API operations.
27
28
```python { .api }
29
class RequestConfig:
30
also_return_response: bool
31
force_fallback_result: bool
32
response_callbacks: list
33
connect_timeout: float
34
timeout: float
35
headers: dict
36
use_msgpack: bool
37
additional_properties: dict
38
def __init__(self, request_options: dict, also_return_response_default: bool): ...
39
```
40
41
**Attributes:**
42
- `also_return_response` (bool): Override global setting for this request
43
- `force_fallback_result` (bool): Force fallback result regardless of success
44
- `response_callbacks` (list): Functions to call during response processing
45
- `connect_timeout` (float): Connection timeout in seconds
46
- `timeout` (float): Request timeout in seconds
47
- `headers` (dict): Additional headers for this request
48
- `use_msgpack` (bool): Use MessagePack encoding for request/response
49
- `additional_properties` (dict): Custom properties for extensions
50
51
**Usage Example:**
52
53
```python
54
from bravado.config import RequestConfig
55
56
# Create per-request configuration
57
request_config = RequestConfig({
58
'timeout': 30.0,
59
'headers': {'X-Custom-Header': 'value'},
60
'use_msgpack': True
61
}, also_return_response_default=False)
62
63
# Use with operation
64
response = client.pet.getPetById(petId=1, _request_config=request_config).response()
65
```
66
67
### Configuration Defaults
68
69
Default configuration values used when no explicit configuration is provided.
70
71
```python { .api }
72
CONFIG_DEFAULTS: dict = {
73
'also_return_response': False,
74
'disable_fallback_results': False,
75
'response_metadata_class': 'bravado.response.BravadoResponseMetadata',
76
'sensitive_headers': ['Authorization']
77
}
78
```
79
80
These defaults provide sensible behavior for most use cases while allowing full customization.
81
82
### Configuration Factory Function
83
84
Utility function to create BravadoConfig objects from dictionary configurations.
85
86
```python { .api }
87
def bravado_config_from_config_dict(config_dict: dict) -> BravadoConfig: ...
88
```
89
90
**Parameters:**
91
- `config_dict` (dict): Configuration dictionary with bravado settings
92
93
**Returns:**
94
- BravadoConfig instance with validated settings
95
96
**Usage Example:**
97
98
```python
99
from bravado.config import bravado_config_from_config_dict
100
101
config_dict = {
102
'also_return_response': True,
103
'disable_fallback_results': False,
104
'sensitive_headers': ['Authorization', 'X-API-Key']
105
}
106
107
bravado_config = bravado_config_from_config_dict(config_dict)
108
```
109
110
## Global Configuration
111
112
Configure bravado behavior globally when creating SwaggerClient instances:
113
114
```python
115
from bravado.client import SwaggerClient
116
117
# Global configuration
118
config = {
119
# Bravado-specific settings
120
'also_return_response': True,
121
'disable_fallback_results': False,
122
'response_metadata_class': 'bravado.response.BravadoResponseMetadata',
123
'sensitive_headers': ['Authorization', 'X-Secret-Key'],
124
125
# bravado-core settings (validation, models, etc.)
126
'validate_requests': True,
127
'validate_responses': True,
128
'use_models': True,
129
'validate_swagger_spec': True,
130
'formats': [], # Custom format validators
131
}
132
133
client = SwaggerClient.from_url(spec_url, config=config)
134
```
135
136
### Response Metadata Customization
137
138
You can provide a custom response metadata class:
139
140
```python
141
from bravado.response import BravadoResponseMetadata
142
143
class CustomResponseMetadata(BravadoResponseMetadata):
144
def __init__(self, *args, **kwargs):
145
super().__init__(*args, **kwargs)
146
self.custom_field = "custom_value"
147
148
@property
149
def custom_property(self):
150
return f"Request took {self.elapsed_time:.2f}s"
151
152
config = {
153
'response_metadata_class': 'myapp.CustomResponseMetadata'
154
}
155
156
client = SwaggerClient.from_url(spec_url, config=config)
157
```
158
159
## Per-Request Configuration
160
161
Override global settings for specific requests using RequestConfig:
162
163
```python
164
from bravado.config import RequestConfig
165
166
# Timeout configuration
167
timeout_config = RequestConfig({
168
'timeout': 60.0, # 60 second timeout
169
'connect_timeout': 10.0 # 10 second connection timeout
170
}, also_return_response_default=False)
171
172
# Custom headers
173
headers_config = RequestConfig({
174
'headers': {
175
'X-Request-ID': 'req-12345',
176
'X-Client-Version': '1.0.0'
177
}
178
}, also_return_response_default=False)
179
180
# Use configurations
181
response1 = client.pet.getPetById(petId=1, _request_config=timeout_config).response()
182
response2 = client.pet.addPet(body=pet_data, _request_config=headers_config).response()
183
```
184
185
### Response Callbacks
186
187
Execute custom logic during response processing:
188
189
```python
190
def log_request_time(response, operation):
191
print(f"Operation {operation.operation_id} took {response.elapsed_time:.2f}s")
192
193
def validate_custom_header(response, operation):
194
if 'X-Custom-Header' not in response.headers:
195
print("Warning: Expected custom header missing")
196
197
callback_config = RequestConfig({
198
'response_callbacks': [log_request_time, validate_custom_header]
199
}, also_return_response_default=True)
200
201
response = client.pet.getPetById(petId=1, _request_config=callback_config).response()
202
```
203
204
### MessagePack Support
205
206
Use MessagePack encoding for better performance with large payloads:
207
208
```python
209
msgpack_config = RequestConfig({
210
'use_msgpack': True,
211
'headers': {'Accept': 'application/msgpack'}
212
}, also_return_response_default=False)
213
214
# Request and response will use MessagePack encoding
215
response = client.pet.addPet(body=large_pet_data, _request_config=msgpack_config).response()
216
```
217
218
## Advanced Configuration Patterns
219
220
### Environment-Based Configuration
221
222
```python
223
import os
224
from bravado.client import SwaggerClient
225
226
def create_client(spec_url):
227
config = {
228
'also_return_response': os.getenv('BRAVADO_RETURN_RESPONSE', 'false').lower() == 'true',
229
'validate_requests': os.getenv('BRAVADO_VALIDATE_REQUESTS', 'true').lower() == 'true',
230
'validate_responses': os.getenv('BRAVADO_VALIDATE_RESPONSES', 'true').lower() == 'true',
231
}
232
233
# Development vs production settings
234
if os.getenv('ENVIRONMENT') == 'development':
235
config.update({
236
'validate_swagger_spec': True,
237
'sensitive_headers': ['Authorization'] # More logging in dev
238
})
239
else:
240
config.update({
241
'validate_swagger_spec': False, # Skip validation in production
242
'sensitive_headers': ['Authorization', 'X-API-Key', 'Cookie']
243
})
244
245
return SwaggerClient.from_url(spec_url, config=config)
246
```
247
248
### Profile-Based Configuration
249
250
```python
251
from dataclasses import dataclass
252
from bravado.config import RequestConfig
253
254
@dataclass
255
class RequestProfile:
256
timeout: float
257
connect_timeout: float
258
retries: int
259
260
def to_request_config(self):
261
return RequestConfig({
262
'timeout': self.timeout,
263
'connect_timeout': self.connect_timeout,
264
'additional_properties': {'retries': self.retries}
265
}, also_return_response_default=True)
266
267
# Define profiles
268
PROFILES = {
269
'fast': RequestProfile(timeout=5.0, connect_timeout=2.0, retries=1),
270
'standard': RequestProfile(timeout=30.0, connect_timeout=10.0, retries=3),
271
'slow': RequestProfile(timeout=120.0, connect_timeout=30.0, retries=5)
272
}
273
274
# Use profiles
275
fast_config = PROFILES['fast'].to_request_config()
276
response = client.pet.getPetById(petId=1, _request_config=fast_config).response()
277
```
278
279
### Configuration Validation
280
281
```python
282
from bravado.config import bravado_config_from_config_dict
283
284
def validate_config(config_dict):
285
"""Validate configuration before creating client."""
286
required_keys = ['also_return_response', 'validate_requests']
287
288
for key in required_keys:
289
if key not in config_dict:
290
raise ValueError(f"Missing required config key: {key}")
291
292
if config_dict.get('timeout', 0) <= 0:
293
raise ValueError("Timeout must be positive")
294
295
return bravado_config_from_config_dict(config_dict)
296
297
# Use validation
298
try:
299
config = validate_config({
300
'also_return_response': True,
301
'validate_requests': True,
302
'timeout': 30.0
303
})
304
client = SwaggerClient.from_url(spec_url, config=config._asdict())
305
except ValueError as e:
306
print(f"Configuration error: {e}")
307
```
308
309
## Configuration Best Practices
310
311
1. **Use Environment Variables**: Configure behavior based on deployment environment
312
2. **Validate Early**: Validate configuration at startup, not during requests
313
3. **Profile-Based Settings**: Create reusable configuration profiles for different use cases
314
4. **Sensitive Data**: Properly configure sensitive_headers to avoid logging credentials
315
5. **Timeout Strategy**: Set appropriate timeouts based on your application's requirements
316
6. **Development vs Production**: Use different validation settings for different environments
317
318
```python
319
# Good configuration example
320
import os
321
from bravado.client import SwaggerClient
322
from bravado.requests_client import RequestsClient
323
324
def create_production_client(spec_url):
325
# Production-optimized HTTP client
326
http_client = RequestsClient(
327
ssl_verify=True, # Always verify SSL in production
328
)
329
330
# Production configuration
331
config = {
332
'also_return_response': True, # Always get metadata for monitoring
333
'validate_requests': True, # Validate requests to catch issues early
334
'validate_responses': False, # Skip response validation for performance
335
'validate_swagger_spec': False, # Skip spec validation for startup performance
336
'sensitive_headers': [ # Comprehensive sensitive header list
337
'Authorization', 'X-API-Key', 'Cookie',
338
'X-Auth-Token', 'X-Session-ID'
339
]
340
}
341
342
return SwaggerClient.from_url(spec_url, http_client=http_client, config=config)
343
344
def create_development_client(spec_url):
345
config = {
346
'also_return_response': True,
347
'validate_requests': True, # Full validation in development
348
'validate_responses': True,
349
'validate_swagger_spec': True,
350
'sensitive_headers': ['Authorization'] # Minimal for easier debugging
351
}
352
353
return SwaggerClient.from_url(spec_url, config=config)
354
355
# Use environment-based client creation
356
if os.getenv('ENVIRONMENT') == 'production':
357
client = create_production_client(spec_url)
358
else:
359
client = create_development_client(spec_url)
360
```