or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auth.mdchannel.mddiscovery.mderrors.mdhttp.mdindex.mdmedia.mdmimeparse.mdmodel.mdschema.mdtesting.md

http.mddocs/

0

# HTTP Request Handling

1

2

The http module provides comprehensive HTTP functionality including individual request execution, batch processing, retry logic, authentication integration, and testing utilities.

3

4

## Capabilities

5

6

### Individual HTTP Requests

7

8

Execute individual HTTP requests with authentication, retry logic, and response processing.

9

10

```python { .api }

11

class HttpRequest:

12

"""Represents an HTTP request to be executed."""

13

14

def __init__(self, http, postproc, uri, method='GET', body=None,

15

headers=None, methodId=None, resumable=None):

16

"""

17

Initialize an HTTP request.

18

19

Args:

20

http (httplib2.Http): HTTP client to use for the request

21

postproc (callable): Function to process the response

22

uri (str): URI for the HTTP request

23

method (str): HTTP method ('GET', 'POST', 'PUT', 'DELETE', etc.)

24

body (str, optional): Request body content

25

headers (dict, optional): HTTP headers for the request

26

methodId (str, optional): API method identifier for logging

27

resumable (MediaUpload, optional): Resumable media upload

28

"""

29

30

def execute(self, http=None, num_retries=0):

31

"""

32

Execute the HTTP request.

33

34

Args:

35

http (httplib2.Http, optional): HTTP client to use (overrides default)

36

num_retries (int): Number of times to retry on recoverable errors

37

38

Returns:

39

object: Deserialized response content based on the response model

40

41

Raises:

42

HttpError: When the HTTP request fails with an error status

43

ResumableUploadError: When resumable upload fails

44

"""

45

46

def add_response_callback(self, cb):

47

"""

48

Add a callback function to process the HTTP response.

49

50

Args:

51

cb (callable): Callback function that takes (resp, content) arguments

52

"""

53

54

def to_json(self):

55

"""

56

Serialize the request to JSON for storage or transmission.

57

58

Returns:

59

str: JSON representation of the request

60

"""

61

62

@staticmethod

63

def from_json(s, http, postproc):

64

"""

65

Deserialize a request from JSON.

66

67

Args:

68

s (str): JSON string representing a request

69

http (httplib2.Http): HTTP client instance

70

postproc (callable): Response post-processing function

71

72

Returns:

73

HttpRequest: Reconstructed request object

74

"""

75

76

def next_chunk(self, http=None, num_retries=0):

77

"""

78

Download the next chunk of a resumable media upload.

79

80

Args:

81

http (httplib2.Http, optional): HTTP client to use

82

num_retries (int): Number of retry attempts

83

84

Returns:

85

tuple: (MediaUploadProgress or None, object or None) -

86

Progress status and response body (None until upload complete)

87

"""

88

89

@staticmethod

90

def null_postproc(resp, contents):

91

"""

92

Default post-processing function that returns response as-is.

93

94

Args:

95

resp: HTTP response object

96

contents: Response body content

97

98

Returns:

99

tuple: (resp, contents) unchanged

100

"""

101

```

102

103

### Batch HTTP Requests

104

105

Execute multiple HTTP requests efficiently in a single batch operation.

106

107

```python { .api }

108

class BatchHttpRequest:

109

"""Batch multiple HTTP requests for efficient execution."""

110

111

def __init__(self, callback=None, batch_uri=None):

112

"""

113

Initialize a batch HTTP request.

114

115

Args:

116

callback (callable, optional): Default callback for all requests

117

batch_uri (str, optional): Custom URI for batch endpoint

118

"""

119

120

def add(self, request, callback=None, request_id=None):

121

"""

122

Add a request to the batch.

123

124

Args:

125

request (HttpRequest): The request to add to the batch

126

callback (callable, optional): Callback for this specific request

127

request_id (str, optional): Unique identifier for this request

128

129

Raises:

130

BatchError: When the batch is full or request is invalid

131

"""

132

133

def execute(self, http=None, num_retries=0):

134

"""

135

Execute all requests in the batch.

136

137

Args:

138

http (httplib2.Http, optional): HTTP client to use

139

num_retries (int): Number of retry attempts for the batch

140

141

Raises:

142

BatchError: When batch execution fails

143

"""

144

```

145

146

### HTTP Constants

147

148

```python { .api }

149

DEFAULT_CHUNK_SIZE = 100 * 1024 * 1024 # 100MB default chunk size

150

MAX_URI_LENGTH = 2048 # Maximum URI length for GET requests

151

MAX_BATCH_LIMIT = 1000 # Maximum requests per batch

152

DEFAULT_HTTP_TIMEOUT_SEC = 60 # Default HTTP timeout in seconds

153

```

154

155

### Media Upload Progress

156

157

Progress tracking for resumable media uploads.

158

159

```python { .api }

160

class MediaUploadProgress:

161

"""Status of a resumable upload."""

162

163

def __init__(self, resumable_progress, total_size):

164

"""

165

Initialize upload progress.

166

167

Args:

168

resumable_progress (int): Bytes sent so far

169

total_size (int or None): Total bytes in complete upload, or None if unknown

170

"""

171

172

def progress(self):

173

"""

174

Get upload progress as a percentage.

175

176

Returns:

177

float: Percent of upload completed (0.0 if total size unknown)

178

"""

179

```

180

181

### Media Download Progress

182

183

Progress tracking for media downloads.

184

185

```python { .api }

186

class MediaDownloadProgress:

187

"""Status of a resumable download."""

188

189

def __init__(self, resumable_progress, total_size):

190

"""

191

Initialize download progress.

192

193

Args:

194

resumable_progress (int): Bytes received so far

195

total_size (int): Total bytes in complete download

196

"""

197

198

def progress(self):

199

"""

200

Get download progress as a percentage.

201

202

Returns:

203

float: Percent of download completed (0.0 if total size unknown)

204

"""

205

```

206

207

### HTTP Testing Utilities

208

209

Mock classes for testing HTTP requests and responses.

210

211

```python { .api }

212

class HttpMock:

213

"""Mock of httplib2.Http for testing."""

214

215

def __init__(self, filename=None, headers=None):

216

"""

217

Initialize HTTP mock.

218

219

Args:

220

filename (str, optional): Absolute path to response file

221

headers (dict, optional): Headers to return (default: {"status": "200"})

222

"""

223

224

def request(self, uri, method="GET", body=None, headers=None,

225

redirections=1, connection_type=None):

226

"""

227

Mock HTTP request.

228

229

Args:

230

uri (str): Request URI

231

method (str): HTTP method

232

body (str, optional): Request body

233

headers (dict, optional): Request headers

234

redirections (int): Number of redirections to follow

235

connection_type: Connection type

236

237

Returns:

238

tuple: (httplib2.Response, bytes or None) - mock response

239

"""

240

241

def close(self):

242

"""Close connections (compatibility method)."""

243

244

class HttpMockSequence:

245

"""Mock a sequence of HTTP responses for testing."""

246

247

def __init__(self, iterable):

248

"""

249

Initialize mock sequence.

250

251

Args:

252

iterable: Sequence of (headers, body) pairs for sequential responses

253

"""

254

255

def request(self, uri, method="GET", body=None, headers=None,

256

redirections=1, connection_type=None):

257

"""

258

Return sequential mock responses.

259

260

Returns:

261

tuple: (httplib2.Response, bytes) - next response in sequence

262

"""

263

```

264

265

### HTTP Utility Functions

266

267

Utility functions for HTTP client configuration and processing.

268

269

```python { .api }

270

def set_user_agent(http, user_agent):

271

"""

272

Set the user-agent header on every request.

273

274

Args:

275

http (httplib2.Http): HTTP client instance

276

user_agent (str): User-agent string

277

278

Returns:

279

httplib2.Http: Modified HTTP client with user-agent injection

280

"""

281

282

def tunnel_patch(http):

283

"""

284

Tunnel PATCH requests over POST for OAuth 1.0 compatibility.

285

286

Args:

287

http (httplib2.Http): HTTP client instance

288

289

Returns:

290

httplib2.Http: Modified HTTP client with PATCH tunneling

291

"""

292

293

def build_http():

294

"""

295

Build an httplib2.Http object with default timeout and redirect handling.

296

297

Returns:

298

httplib2.Http: HTTP client with default configuration

299

"""

300

```

301

302

## Usage Examples

303

304

### Basic Request Execution

305

306

```python

307

from googleapiclient import discovery

308

309

# Build service and create request

310

service = discovery.build('gmail', 'v1', credentials=credentials)

311

request = service.users().messages().list(userId='me', maxResults=10)

312

313

# Execute with retry

314

try:

315

response = request.execute(num_retries=3)

316

print(f"Found {len(response.get('messages', []))} messages")

317

except Exception as e:

318

print(f"Request failed: {e}")

319

```

320

321

### Request Serialization and Deserialization

322

323

```python

324

from googleapiclient import discovery

325

from googleapiclient.http import HttpRequest

326

import json

327

328

# Create and serialize request

329

service = discovery.build('gmail', 'v1', credentials=credentials)

330

request = service.users().messages().get(userId='me', id='message_id')

331

request_json = request.to_json()

332

333

# Store or transmit request_json...

334

335

# Recreate request from JSON

336

restored_request = HttpRequest.from_json(request_json)

337

response = restored_request.execute()

338

```

339

340

### Response Callbacks

341

342

```python

343

def response_callback(resp, content):

344

print(f"Response status: {resp.status}")

345

print(f"Response headers: {resp}")

346

print(f"Content length: {len(content) if content else 0}")

347

348

request = service.users().messages().list(userId='me')

349

request.add_response_callback(response_callback)

350

response = request.execute()

351

```

352

353

### Batch Request Processing

354

355

```python

356

from googleapiclient import http

357

358

def batch_callback(request_id, response, exception):

359

"""Handle individual batch request results."""

360

if exception is not None:

361

print(f'Request {request_id} failed: {exception}')

362

else:

363

print(f'Request {request_id} succeeded: {response}')

364

365

# Create batch request

366

batch = http.BatchHttpRequest(callback=batch_callback)

367

368

# Add multiple requests to batch

369

message_ids = ['msg1', 'msg2', 'msg3', 'msg4', 'msg5']

370

for i, msg_id in enumerate(message_ids):

371

request = service.users().messages().get(userId='me', id=msg_id)

372

batch.add(request, request_id=f'message_{i}')

373

374

# Execute all requests in batch

375

batch.execute()

376

```

377

378

### Batch with Custom Callbacks

379

380

```python

381

def process_message(request_id, response, exception):

382

if exception:

383

print(f"Failed to get message {request_id}: {exception}")

384

else:

385

subject = 'No subject'

386

for header in response.get('payload', {}).get('headers', []):

387

if header['name'] == 'Subject':

388

subject = header['value']

389

break

390

print(f"Message {request_id}: {subject}")

391

392

def process_label(request_id, response, exception):

393

if exception:

394

print(f"Failed to get label {request_id}: {exception}")

395

else:

396

print(f"Label {request_id}: {response.get('name', 'Unknown')}")

397

398

batch = http.BatchHttpRequest()

399

400

# Add requests with different callbacks

401

batch.add(

402

service.users().messages().get(userId='me', id='msg1'),

403

callback=process_message,

404

request_id='message_1'

405

)

406

batch.add(

407

service.users().labels().get(userId='me', id='INBOX'),

408

callback=process_label,

409

request_id='inbox_label'

410

)

411

412

batch.execute()

413

```

414

415

### Error Handling with Retries

416

417

```python

418

from googleapiclient.errors import HttpError

419

import time

420

421

def execute_with_backoff(request, max_retries=3):

422

"""Execute request with exponential backoff."""

423

for attempt in range(max_retries):

424

try:

425

return request.execute()

426

except HttpError as error:

427

if error.resp.status in [429, 500, 502, 503, 504]:

428

if attempt < max_retries - 1:

429

wait_time = (2 ** attempt) + (random.randint(0, 1000) / 1000)

430

time.sleep(wait_time)

431

continue

432

raise

433

434

# Use custom retry logic

435

request = service.users().messages().list(userId='me')

436

response = execute_with_backoff(request)

437

```

438

439

### Working with Large Result Sets

440

441

```python

442

def get_all_messages(service, user_id='me'):

443

"""Get all messages using pagination."""

444

messages = []

445

request = service.users().messages().list(userId=user_id)

446

447

while request is not None:

448

response = request.execute()

449

messages.extend(response.get('messages', []))

450

request = service.users().messages().list_next(request, response)

451

452

return messages

453

454

all_messages = get_all_messages(service)

455

print(f"Total messages: {len(all_messages)}")

456

```