or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdclient-management.mdconfiguration.mdexception-handling.mdhttp-clients.mdindex.mdresponse-handling.mdspec-loading.mdtesting-utilities.md

response-handling.mddocs/

0

# Response Handling

1

2

Comprehensive response processing with metadata, timing information, fallback mechanisms, and both synchronous/asynchronous response patterns. The response handling system provides rich information about HTTP requests and supports fallback results for resilient applications.

3

4

## Capabilities

5

6

### HttpFuture

7

8

Wrapper for HTTP client futures that provides consistent response handling across different HTTP client implementations. This is the primary interface for getting results from API operations.

9

10

```python { .api }

11

class HttpFuture:

12

def __init__(self, future, response_adapter, operation=None, request_config=None): ...

13

def response(self, timeout: float = None, fallback_result=None, exceptions_to_catch: tuple = None) -> BravadoResponse: ...

14

def result(self, timeout: float = None): ... # DEPRECATED

15

def cancel(self): ...

16

```

17

18

**Parameters:**

19

- `future`: Underlying HTTP client future (FutureAdapter instance)

20

- `response_adapter`: Adapter for converting HTTP responses

21

- `operation`: bravado_core.operation.Operation object

22

- `request_config`: RequestConfig instance

23

- `timeout` (float): Timeout in seconds for the operation

24

- `fallback_result`: Value to return if operation fails with specified exceptions

25

- `exceptions_to_catch` (tuple): Exception types that trigger fallback behavior

26

27

**Returns:**

28

- `response()`: BravadoResponse object containing result and metadata

29

- `result()`: Direct result (deprecated, use response().result instead)

30

31

**Usage Example:**

32

33

```python

34

from bravado.client import SwaggerClient

35

36

client = SwaggerClient.from_url('http://petstore.swagger.io/v2/swagger.json')

37

38

# Get HttpFuture from operation

39

future = client.pet.getPetById(petId=1)

40

41

# Get response with metadata (recommended)

42

response = future.response(timeout=10.0)

43

pet_data = response.result

44

status_code = response.metadata.status_code

45

request_time = response.metadata.elapsed_time

46

47

# With fallback result for resilience

48

response = future.response(

49

timeout=5.0,

50

fallback_result={'name': 'Unknown Pet', 'status': 'unavailable'}

51

)

52

```

53

54

### BravadoResponse

55

56

Response object containing both the unmarshalled result and comprehensive metadata about the HTTP request and response.

57

58

```python { .api }

59

class BravadoResponse:

60

result: Any

61

metadata: BravadoResponseMetadata

62

@property

63

def incoming_response(self) -> IncomingResponse: ...

64

```

65

66

**Attributes:**

67

- `result`: The unmarshalled response data (could be a model object, dict, list, or primitive)

68

- `metadata`: BravadoResponseMetadata object with timing and HTTP information

69

70

**Properties:**

71

- `incoming_response`: Access to the underlying HTTP response object

72

73

**Usage Example:**

74

75

```python

76

response = client.pet.getPetById(petId=1).response()

77

78

# Access result data

79

pet_name = response.result.name

80

pet_status = response.result.status

81

82

# Access response metadata

83

print(f"Status: {response.metadata.status_code}")

84

print(f"Request took: {response.metadata.elapsed_time:.2f}s")

85

print(f"Response headers: {response.metadata.headers}")

86

87

# Access raw HTTP response if needed

88

raw_response = response.incoming_response

89

raw_text = raw_response.text

90

```

91

92

### BravadoResponseMetadata

93

94

HTTP response metadata containing timing information, exception details, and request configuration used.

95

96

```python { .api }

97

class BravadoResponseMetadata:

98

start_time: float

99

request_end_time: float

100

processing_end_time: float

101

handled_exception_info: tuple

102

request_config: RequestConfig

103

def __init__(self, incoming_response, swagger_result, start_time: float, request_end_time: float, handled_exception_info: tuple, request_config: RequestConfig): ...

104

@property

105

def incoming_response(self) -> IncomingResponse: ...

106

@property

107

def status_code(self) -> int: ...

108

@property

109

def headers(self) -> dict: ...

110

@property

111

def is_fallback_result(self) -> bool: ...

112

@property

113

def request_elapsed_time(self) -> float: ...

114

@property

115

def elapsed_time(self) -> float: ...

116

```

117

118

**Attributes:**

119

- `start_time` (float): Monotonic timestamp when the future was created

120

- `request_end_time` (float): Monotonic timestamp when HTTP response was received

121

- `processing_end_time` (float): Monotonic timestamp when response processing ended

122

- `handled_exception_info` (tuple): Exception information if an exception was caught during processing

123

- `request_config`: RequestConfig instance used for the request

124

125

**Properties:**

126

- `incoming_response`: Underlying HTTP response object

127

- `status_code` (int): HTTP status code

128

- `headers` (dict): HTTP response headers

129

- `is_fallback_result` (bool): True if result came from fallback mechanism

130

- `request_elapsed_time` (float): Time spent on HTTP request only

131

- `elapsed_time` (float): Total time including response processing

132

133

**Usage Example:**

134

135

```python

136

response = client.pet.getPetById(petId=1).response()

137

metadata = response.metadata

138

139

# Timing information

140

print(f"Request time: {metadata.request_elapsed_time:.3f}s")

141

print(f"Total time: {metadata.elapsed_time:.3f}s")

142

print(f"Processing time: {metadata.elapsed_time - metadata.request_elapsed_time:.3f}s")

143

144

# HTTP details

145

print(f"Status: {metadata.status_code}")

146

print(f"Content-Type: {metadata.headers.get('content-type')}")

147

148

# Check if fallback was used

149

if metadata.is_fallback_result:

150

print("Response came from fallback mechanism")

151

```

152

153

### FutureAdapter (Base Class)

154

155

Abstract base class for HTTP client future adapters that standardizes the interface across different HTTP libraries.

156

157

```python { .api }

158

class FutureAdapter:

159

timeout_errors: tuple # Must be defined by subclasses

160

connection_errors: tuple # Must be defined by subclasses

161

def result(self, timeout: float = None): ...

162

def cancel(self): ...

163

```

164

165

**Attributes:**

166

- `timeout_errors` (tuple): Exception types that indicate timeout errors

167

- `connection_errors` (tuple): Exception types that indicate connection errors

168

169

**Methods:**

170

- `result()`: Get the result (blocking operation)

171

- `cancel()`: Cancel the underlying operation

172

173

## Fallback Mechanisms

174

175

Bravado supports fallback results for building resilient applications that can handle service failures gracefully.

176

177

### Default Fallback Exceptions

178

179

```python { .api }

180

FALLBACK_EXCEPTIONS: tuple # (BravadoTimeoutError, BravadoConnectionError, HTTPServerError)

181

SENTINEL: object # Sentinel value used for fallback result detection

182

```

183

184

These exceptions will trigger fallback behavior by default. The SENTINEL value is used internally to detect when no fallback result is provided.

185

186

### Using Fallback Results

187

188

```python

189

from bravado.exception import BravadoTimeoutError, HTTPServerError

190

191

# Basic fallback

192

response = future.response(

193

timeout=5.0,

194

fallback_result={'error': 'Service unavailable'}

195

)

196

197

# Custom exception handling

198

response = future.response(

199

timeout=10.0,

200

fallback_result={'pets': []},

201

exceptions_to_catch=(BravadoTimeoutError, HTTPServerError)

202

)

203

204

# Check if fallback was used

205

if response.metadata.is_fallback_result:

206

print("Using fallback data due to service failure")

207

# Handle degraded functionality

208

else:

209

print("Got live data from service")

210

# Normal processing

211

```

212

213

## Response Processing Functions

214

215

Utility functions for processing and unmarshalling HTTP responses.

216

217

```python { .api }

218

def unmarshal_response(incoming_response: IncomingResponse, operation, response_callbacks: list = None): ...

219

def unmarshal_response_inner(response, op): ...

220

def raise_on_unexpected(http_response: IncomingResponse): ...

221

def raise_on_expected(http_response: IncomingResponse): ...

222

def reraise_errors(func): ...

223

```

224

225

**Parameters:**

226

- `incoming_response`: HTTP response to process

227

- `operation`: Operation that generated the response

228

- `response_callbacks` (list): Callback functions to execute during processing

229

- `http_response`: HTTP response to check for errors

230

- `func`: Function to wrap with error handling

231

232

These functions are typically used internally but can be useful for custom response processing.

233

234

## Response Callbacks

235

236

You can register callbacks to be executed during response processing:

237

238

```python

239

from bravado.config import RequestConfig

240

241

def log_response(response, operation_name):

242

print(f"Operation {operation_name} completed with status {response.status_code}")

243

244

request_config = RequestConfig(

245

response_callbacks=[

246

lambda resp, op: log_response(resp, op.operation_id)

247

]

248

)

249

250

future = client.pet.getPetById(petId=1, _request_config=request_config)

251

response = future.response()

252

```

253

254

## Async Response Handling

255

256

When using FidoClient, response handling integrates with Twisted's event loop:

257

258

```python

259

from bravado.fido_client import FidoClient

260

from twisted.internet import defer

261

262

@defer.inlineCallbacks

263

def get_pet_async():

264

http_client = FidoClient()

265

client = SwaggerClient.from_url(spec_url, http_client=http_client)

266

267

future = client.pet.getPetById(petId=1)

268

response = yield future.response()

269

270

defer.returnValue(response.result)

271

```

272

273

## Performance Considerations

274

275

- Use `response()` method instead of deprecated `result()` method

276

- Consider fallback results for non-critical operations

277

- Monitor timing information for performance optimization

278

- Use appropriate timeout values based on your application needs

279

280

```python

281

# Good: Reasonable timeout with fallback

282

response = future.response(

283

timeout=30.0, # 30 second timeout

284

fallback_result=None # Graceful degradation

285

)

286

287

# Monitor performance

288

if response.metadata.elapsed_time > 1.0:

289

print(f"Slow response detected: {response.metadata.elapsed_time:.2f}s")

290

```