or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

adapters.mdauthentication.mdcookies.mdexceptions.mdhooks.mdhttp-methods.mdindex.mdmodels.mdsessions.mdstatus-codes.mdstructures.md

structures.mddocs/

0

# Data Structures

1

2

Data structure classes that provide enhanced dictionary interfaces with special behaviors for HTTP-related operations. These structures are used throughout the requests library for headers, status codes, and general data handling.

3

4

## Capabilities

5

6

### CaseInsensitiveDict Class

7

8

Dictionary with case-insensitive key lookup, primarily used for HTTP headers.

9

10

```python { .api }

11

class CaseInsensitiveDict(dict):

12

"""

13

A case-insensitive dictionary implementation.

14

15

Used for HTTP headers where keys should be treated case-insensitively

16

according to HTTP specification.

17

"""

18

19

def __init__(self, data=None, **kwargs):

20

"""

21

Initialize CaseInsensitiveDict.

22

23

Parameters:

24

- data: Initial data (dict, list of tuples, or another CaseInsensitiveDict)

25

- **kwargs: Additional key-value pairs

26

"""

27

28

def __setitem__(self, key, value):

29

"""Set value with case-insensitive key."""

30

31

def __getitem__(self, key):

32

"""Get value with case-insensitive key lookup."""

33

34

def __delitem__(self, key):

35

"""Delete item with case-insensitive key lookup."""

36

37

def __iter__(self):

38

"""Iterate over original-case keys."""

39

40

def __len__(self) -> int:

41

"""Get number of items."""

42

43

def __eq__(self, other) -> bool:

44

"""Compare with another mapping (case-insensitive)."""

45

46

def __repr__(self) -> str:

47

"""String representation."""

48

49

def lower_items(self):

50

"""

51

Iterate over (lowercase_key, value) pairs.

52

53

Yields:

54

Tuples of (lowercase_key, value)

55

"""

56

57

def copy(self) -> 'CaseInsensitiveDict':

58

"""Create a copy of the dictionary."""

59

```

60

61

### LookupDict Class

62

63

Dictionary subclass with attribute-style access, used for status codes.

64

65

```python { .api }

66

class LookupDict(dict):

67

"""

68

A dictionary that supports both item and attribute access.

69

70

Used for status codes to enable both codes['ok'] and codes.ok syntax.

71

"""

72

73

def __init__(self, name=None):

74

"""

75

Initialize LookupDict.

76

77

Parameters:

78

- name: Optional name for the lookup dict

79

"""

80

81

def __getitem__(self, key):

82

"""Get item with fallback to __dict__ lookup."""

83

84

def get(self, key, default=None):

85

"""

86

Get value with default.

87

88

Parameters:

89

- key: Key to look up

90

- default: Default value if key not found

91

92

Returns:

93

Value or default

94

"""

95

96

def __repr__(self) -> str:

97

"""String representation."""

98

```

99

100

## Usage Examples

101

102

### CaseInsensitiveDict Usage

103

104

```python

105

import requests

106

from requests.structures import CaseInsensitiveDict

107

108

# CaseInsensitiveDict is used for response headers

109

response = requests.get('https://httpbin.org/get')

110

headers = response.headers

111

112

# All these access the same header (case-insensitive)

113

print(headers['Content-Type']) # Works

114

print(headers['content-type']) # Works

115

print(headers['CONTENT-TYPE']) # Works

116

print(headers['Content-type']) # Works

117

118

# Check header existence (case-insensitive)

119

print('content-type' in headers) # True

120

print('Content-Type' in headers) # True

121

122

# Iterate over headers (preserves original case)

123

for name, value in headers.items():

124

print(f"{name}: {value}")

125

```

126

127

### Manual CaseInsensitiveDict Creation

128

129

```python

130

from requests.structures import CaseInsensitiveDict

131

132

# Create from dict

133

headers = CaseInsensitiveDict({

134

'Content-Type': 'application/json',

135

'Authorization': 'Bearer token123',

136

'User-Agent': 'MyApp/1.0'

137

})

138

139

# Access with any case

140

print(headers['content-type']) # 'application/json'

141

print(headers['AUTHORIZATION']) # 'Bearer token123'

142

print(headers['user-agent']) # 'MyApp/1.0'

143

144

# Set with any case

145

headers['accept'] = 'application/json'

146

headers['CACHE-CONTROL'] = 'no-cache'

147

148

# Check existence (case-insensitive)

149

print('Accept' in headers) # True

150

print('cache-control' in headers) # True

151

152

# Delete with any case

153

del headers['USER-AGENT']

154

print('user-agent' in headers) # False

155

```

156

157

### CaseInsensitiveDict Operations

158

159

```python

160

from requests.structures import CaseInsensitiveDict

161

162

# Create from various sources

163

headers1 = CaseInsensitiveDict([

164

('Content-Type', 'application/json'),

165

('Accept', 'application/json')

166

])

167

168

headers2 = CaseInsensitiveDict(

169

authorization='Bearer token',

170

user_agent='MyApp/1.0'

171

)

172

173

# Copy dictionary

174

headers_copy = headers1.copy()

175

headers_copy['X-Custom'] = 'custom-value'

176

177

# Compare dictionaries (case-insensitive)

178

h1 = CaseInsensitiveDict({'Content-Type': 'application/json'})

179

h2 = CaseInsensitiveDict({'content-type': 'application/json'})

180

print(h1 == h2) # True (case-insensitive comparison)

181

182

# Get lowercase items for processing

183

headers = CaseInsensitiveDict({

184

'Content-Type': 'application/json',

185

'Accept': 'application/json',

186

'Authorization': 'Bearer token'

187

})

188

189

for lower_key, value in headers.lower_items():

190

print(f"{lower_key}: {value}")

191

# content-type: application/json

192

# accept: application/json

193

# authorization: Bearer token

194

```

195

196

### LookupDict Usage

197

198

```python

199

import requests

200

201

# LookupDict is used for status codes

202

codes = requests.codes

203

204

# Attribute access

205

print(codes.ok) # 200

206

print(codes.not_found) # 404

207

print(codes.internal_server_error) # 500

208

209

# Dictionary access

210

print(codes['ok']) # 200

211

print(codes['not_found']) # 404

212

print(codes['server_error']) # 500

213

214

# Both work the same way

215

status_code = 404

216

if status_code == codes.not_found:

217

print("Resource not found")

218

219

if status_code == codes['not_found']:

220

print("Resource not found")

221

```

222

223

### Custom LookupDict

224

225

```python

226

from requests.structures import LookupDict

227

228

# Create custom lookup dict

229

http_methods = LookupDict('HTTP Methods')

230

http_methods.update({

231

'get': 'GET',

232

'post': 'POST',

233

'put': 'PUT',

234

'delete': 'DELETE',

235

'head': 'HEAD',

236

'options': 'OPTIONS',

237

'patch': 'PATCH'

238

})

239

240

# Use both access methods

241

print(http_methods.get) # 'GET'

242

print(http_methods['post']) # 'POST'

243

print(http_methods.delete) # 'DELETE'

244

245

# Get with default

246

print(http_methods.get('trace', 'TRACE')) # 'TRACE'

247

print(http_methods.get('connect')) # None

248

```

249

250

### Practical Header Management

251

252

```python

253

import requests

254

from requests.structures import CaseInsensitiveDict

255

256

def build_headers(content_type=None, auth_token=None, custom_headers=None):

257

"""Build headers with case-insensitive handling."""

258

headers = CaseInsensitiveDict()

259

260

# Set standard headers

261

headers['User-Agent'] = 'MyApp/2.0'

262

263

if content_type:

264

headers['Content-Type'] = content_type

265

266

if auth_token:

267

headers['Authorization'] = f'Bearer {auth_token}'

268

269

# Merge custom headers (case-insensitive)

270

if custom_headers:

271

for key, value in custom_headers.items():

272

headers[key] = value

273

274

return headers

275

276

# Build headers

277

headers = build_headers(

278

content_type='application/json',

279

auth_token='abc123',

280

custom_headers={

281

'x-api-version': '2.0',

282

'X-CUSTOM-HEADER': 'custom-value'

283

}

284

)

285

286

# Use with request

287

response = requests.post('https://httpbin.org/post',

288

headers=headers,

289

json={'key': 'value'})

290

291

# Examine sent headers (case preserved)

292

sent_headers = response.request.headers

293

for name, value in sent_headers.items():

294

print(f"{name}: {value}")

295

```

296

297

### Header Manipulation

298

299

```python

300

import requests

301

from requests.structures import CaseInsensitiveDict

302

303

# Start with response headers

304

response = requests.get('https://httpbin.org/response-headers?foo=bar')

305

headers = response.headers

306

307

print(f"Original headers: {len(headers)} items")

308

309

# Modify headers (case-insensitive)

310

modified_headers = headers.copy()

311

modified_headers['cache-control'] = 'no-cache' # Might overwrite Cache-Control

312

modified_headers['X-Custom'] = 'custom-value' # Add new header

313

del modified_headers['date'] # Remove Date header

314

315

# Use modified headers in new request

316

new_response = requests.get('https://httpbin.org/headers',

317

headers=modified_headers)

318

319

# Check what was sent

320

request_headers = new_response.json()['headers']

321

for name, value in request_headers.items():

322

print(f"{name}: {value}")

323

```

324

325

### Session Header Management

326

327

```python

328

import requests

329

from requests.structures import CaseInsensitiveDict

330

331

# Session headers are CaseInsensitiveDict

332

session = requests.Session()

333

print(type(session.headers)) # <class 'requests.structures.CaseInsensitiveDict'>

334

335

# Set session headers (case-insensitive)

336

session.headers.update({

337

'User-Agent': 'MyApp/1.0',

338

'accept': 'application/json',

339

'AUTHORIZATION': 'Bearer token123'

340

})

341

342

# Check headers with different cases

343

print('user-agent' in session.headers) # True

344

print(session.headers['Accept']) # 'application/json'

345

print(session.headers['authorization']) # 'Bearer token123'

346

347

# Headers persist across requests

348

response1 = session.get('https://httpbin.org/headers')

349

response2 = session.post('https://httpbin.org/post', json={'data': 'test'})

350

351

# Both requests include the session headers

352

print("Request 1 headers:", response1.json()['headers'])

353

print("Request 2 headers:", response2.json()['headers'])

354

```

355

356

### Status Code Management

357

358

```python

359

import requests

360

from requests.structures import LookupDict

361

362

# The codes object is a LookupDict

363

print(type(requests.codes)) # <class 'requests.structures.LookupDict'>

364

365

# Create custom status mappings

366

api_codes = LookupDict('API Status Codes')

367

api_codes.update({

368

'success': 200,

369

'created': 201,

370

'accepted': 202,

371

'bad_request': 400,

372

'unauthorized': 401,

373

'forbidden': 403,

374

'not_found': 404,

375

'server_error': 500

376

})

377

378

# Use in response handling

379

def handle_api_response(response):

380

status = response.status_code

381

382

if status == api_codes.success:

383

return response.json()

384

elif status == api_codes.created:

385

print("Resource created")

386

return response.json()

387

elif status == api_codes.not_found:

388

print("Resource not found")

389

return None

390

elif status == api_codes.server_error:

391

print("Server error occurred")

392

return None

393

else:

394

print(f"Unexpected status: {status}")

395

return None

396

397

# Test with different responses

398

responses = [

399

requests.get('https://httpbin.org/status/200'),

400

requests.get('https://httpbin.org/status/404'),

401

requests.get('https://httpbin.org/status/500')

402

]

403

404

for resp in responses:

405

result = handle_api_response(resp)

406

print(f"Status {resp.status_code}: {result}")

407

```

408

409

## Structure Comparison

410

411

### Standard Dict vs CaseInsensitiveDict

412

413

```python

414

from requests.structures import CaseInsensitiveDict

415

416

# Standard dict - case-sensitive

417

standard = {'Content-Type': 'application/json'}

418

print('content-type' in standard) # False

419

print('Content-Type' in standard) # True

420

421

# CaseInsensitiveDict - case-insensitive

422

case_insensitive = CaseInsensitiveDict({'Content-Type': 'application/json'})

423

print('content-type' in case_insensitive) # True

424

print('Content-Type' in case_insensitive) # True

425

print('CONTENT-TYPE' in case_insensitive) # True

426

427

# Key preservation

428

print(list(standard.keys())) # ['Content-Type']

429

print(list(case_insensitive.keys())) # ['Content-Type'] (original case preserved)

430

431

# Lowercase iteration

432

for key, value in case_insensitive.lower_items():

433

print(f"Lowercase: {key} -> {value}") # content-type -> application/json

434

```

435

436

### Standard Dict vs LookupDict

437

438

```python

439

from requests.structures import LookupDict

440

441

# Standard dict - item access only

442

standard = {'ok': 200, 'not_found': 404}

443

print(standard['ok']) # 200

444

# print(standard.ok) # AttributeError

445

446

# LookupDict - both item and attribute access

447

lookup = LookupDict()

448

lookup.update({'ok': 200, 'not_found': 404})

449

print(lookup['ok']) # 200

450

print(lookup.ok) # 200 (attribute access)

451

print(lookup.not_found) # 404

452

453

# Graceful handling of missing keys

454

print(lookup.get('missing')) # None

455

print(lookup.get('missing', 'default')) # 'default'

456

```