or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcaching.mderror-handling.mdhttp-client.mdindex.mdproxy-support.mdresponse-handling.mdutilities.md

response-handling.mddocs/

0

# Response Handling

1

2

Response objects provide access to HTTP status codes, headers, and response metadata. Response objects behave like dictionaries for header access while providing additional status information and response details.

3

4

## Capabilities

5

6

### Response Class

7

8

HTTP response object that extends Python's dict class to provide dictionary-like access to headers while maintaining response status and metadata.

9

10

```python { .api }

11

class Response(dict):

12

"""

13

HTTP response containing status code, headers, and metadata.

14

Inherits from dict to provide header access via dictionary interface.

15

"""

16

17

def __init__(self, info):

18

"""

19

Initialize response from HTTP response info.

20

21

Args:

22

info: Either email.message or httplib.HTTPResponse object

23

"""

24

25

# Dictionary methods inherited from dict

26

# Additional attributes available:

27

# - status: HTTP status code (int)

28

# - reason: HTTP reason phrase (str)

29

# - version: HTTP version (int)

30

```

31

32

### Response Attributes

33

34

Response objects provide several key attributes:

35

36

```python { .api }

37

# Status information

38

response.status # HTTP status code (200, 404, 500, etc.)

39

response.reason # Reason phrase ("OK", "Not Found", etc.)

40

response.version # HTTP version (11 for HTTP/1.1)

41

42

# Dictionary interface for headers

43

response['content-type'] # Access headers by name

44

response['content-length'] # All header names are lowercase

45

response['cache-control'] # Headers stored as strings

46

response.get('etag', None) # Use dict methods for safe access

47

```

48

49

### Usage Examples

50

51

#### Accessing Response Status

52

53

```python

54

import httplib2

55

56

h = httplib2.Http()

57

(resp, content) = h.request("http://example.org/")

58

59

# Check status code

60

if resp.status == 200:

61

print("Request successful")

62

elif resp.status == 404:

63

print("Resource not found")

64

else:

65

print(f"Request failed with status {resp.status}: {resp.reason}")

66

```

67

68

#### Working with Headers

69

70

```python

71

import httplib2

72

73

h = httplib2.Http()

74

(resp, content) = h.request("http://example.org/")

75

76

# Access headers (case-insensitive, stored as lowercase)

77

content_type = resp['content-type']

78

content_length = resp.get('content-length', 'unknown')

79

server = resp.get('server', 'unknown')

80

81

# Check if header exists

82

if 'etag' in resp:

83

etag = resp['etag']

84

print(f"ETag: {etag}")

85

86

# Iterate over all headers

87

for header_name, header_value in resp.items():

88

print(f"{header_name}: {header_value}")

89

```

90

91

#### Cache-Related Headers

92

93

```python

94

import httplib2

95

96

h = httplib2.Http(".cache")

97

(resp, content) = h.request("http://example.org/")

98

99

# Check caching headers

100

cache_control = resp.get('cache-control', '')

101

expires = resp.get('expires', '')

102

etag = resp.get('etag', '')

103

last_modified = resp.get('last-modified', '')

104

105

print(f"Cache-Control: {cache_control}")

106

print(f"ETag: {etag}")

107

print(f"Last-Modified: {last_modified}")

108

109

# Check if response was served from cache

110

# (httplib2 adds custom headers to indicate cache status)

111

if 'fromcache' in resp:

112

print("Response served from cache")

113

```

114

115

#### Content Type and Encoding

116

117

```python

118

import httplib2

119

120

h = httplib2.Http()

121

(resp, content) = h.request("http://example.org/")

122

123

# Parse content type

124

content_type = resp.get('content-type', '')

125

if 'application/json' in content_type:

126

import json

127

data = json.loads(content.decode('utf-8'))

128

elif 'text/html' in content_type:

129

html = content.decode('utf-8')

130

elif 'image/' in content_type:

131

# Binary image data

132

with open('image.jpg', 'wb') as f:

133

f.write(content)

134

135

# Check encoding from content-type header

136

if 'charset=' in content_type:

137

charset = content_type.split('charset=')[1].split(';')[0]

138

text = content.decode(charset)

139

else:

140

# Default to UTF-8

141

text = content.decode('utf-8')

142

```

143

144

#### Authentication Headers

145

146

```python

147

import httplib2

148

149

h = httplib2.Http()

150

(resp, content) = h.request("http://example.org/protected")

151

152

# Check authentication requirements

153

if resp.status == 401:

154

www_auth = resp.get('www-authenticate', '')

155

if 'Basic' in www_auth:

156

print("Server requires Basic authentication")

157

elif 'Digest' in www_auth:

158

print("Server requires Digest authentication")

159

160

# Add credentials and retry

161

h.add_credentials('username', 'password')

162

(resp, content) = h.request("http://example.org/protected")

163

```

164

165

#### Redirect Information

166

167

```python

168

import httplib2

169

170

h = httplib2.Http()

171

(resp, content) = h.request("http://example.org/redirect")

172

173

# Check for redirects

174

if resp.status in (301, 302, 303, 307, 308):

175

location = resp.get('location', '')

176

print(f"Redirected to: {location}")

177

178

# httplib2 follows redirects automatically by default

179

# The final response will have the status of the final destination

180

```

181

182

### Response Processing Patterns

183

184

#### Error Handling

185

186

```python

187

import httplib2

188

189

h = httplib2.Http()

190

191

try:

192

(resp, content) = h.request("http://example.org/api/data")

193

194

if resp.status == 200:

195

# Success

196

data = content.decode('utf-8')

197

elif resp.status == 404:

198

print("Resource not found")

199

elif resp.status >= 400:

200

print(f"Client error: {resp.status} {resp.reason}")

201

elif resp.status >= 500:

202

print(f"Server error: {resp.status} {resp.reason}")

203

204

except httplib2.HttpLib2Error as e:

205

print(f"HTTP error: {e}")

206

```

207

208

#### Content Negotiation

209

210

```python

211

import httplib2

212

213

h = httplib2.Http()

214

headers = {'Accept': 'application/json, text/xml, */*'}

215

216

(resp, content) = h.request("http://api.example.com/data", headers=headers)

217

218

content_type = resp.get('content-type', '')

219

if 'application/json' in content_type:

220

import json

221

data = json.loads(content.decode('utf-8'))

222

elif 'text/xml' in content_type or 'application/xml' in content_type:

223

import xml.etree.ElementTree as ET

224

root = ET.fromstring(content.decode('utf-8'))

225

else:

226

# Handle other content types

227

text = content.decode('utf-8')

228

```

229

230

### Header Name Normalization

231

232

All header names in Response objects are normalized to lowercase for consistent access:

233

234

- `Content-Type` becomes `content-type`

235

- `Content-Length` becomes `content-length`

236

- `Cache-Control` becomes `cache-control`

237

- `WWW-Authenticate` becomes `www-authenticate`

238

239

This normalization ensures reliable header access regardless of how the server sends the headers.