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

model.mddocs/

0

# Data Models and Request Processing

1

2

The model module provides data models for handling different request and response formats including JSON, raw data, media, and protocol buffers. These models control how request parameters are serialized and how responses are processed.

3

4

## Capabilities

5

6

### Base Model Classes

7

8

Abstract base classes that define the model interface for all data formats.

9

10

```python { .api }

11

class Model:

12

"""Model base class.

13

14

All Model classes should implement this interface. The Model serializes and

15

de-serializes between a wire format such as JSON and a Python object representation.

16

"""

17

18

def request(self, headers, path_params, query_params, body_value):

19

"""

20

Updates the request with serialized body and appropriate headers.

21

22

Args:

23

headers (dict): HTTP headers dictionary to modify

24

path_params (dict): Parameters for URL path substitution

25

query_params (dict): Query string parameters

26

body_value (object): Request body data to serialize

27

28

Returns:

29

tuple: (headers, path_params, query, body) - processed request components

30

"""

31

32

def response(self, resp, content):

33

"""

34

Converts the HTTP response into a Python object.

35

36

Args:

37

resp (httplib2.Response): HTTP response object

38

content (bytes): Response body content

39

40

Returns:

41

object: Deserialized Python object representation

42

43

Raises:

44

googleapiclient.errors.HttpError: For non-2xx HTTP responses

45

"""

46

47

class BaseModel(Model):

48

"""Base model class.

49

50

Subclasses should provide implementations for the 'serialize' and 'deserialize'

51

methods, as well as values for the following class attributes:

52

- accept: HTTP Accept header value

53

- content_type: HTTP Content-type header value

54

- no_content_response: Value for 204 No Content responses

55

- alt_param: Value for "alt" query parameter

56

"""

57

58

accept = None

59

content_type = None

60

no_content_response = None

61

alt_param = None

62

63

def request(self, headers, path_params, query_params, body_value, api_version=None):

64

"""

65

Enhanced request method with API version support.

66

67

Args:

68

headers (dict): HTTP headers dictionary to modify

69

path_params (dict): Parameters for URL path substitution

70

query_params (dict): Query string parameters

71

body_value (object): Request body data to serialize

72

api_version (str, optional): API version for request metadata

73

74

Returns:

75

tuple: (headers, path_params, query, body) - processed request components

76

"""

77

78

def response(self, resp, content):

79

"""

80

Process HTTP response with error handling.

81

82

Args:

83

resp (httplib2.Response): HTTP response object

84

content (bytes): Response body content

85

86

Returns:

87

object: Deserialized response object

88

"""

89

90

def serialize(self, body_value):

91

"""

92

Serialize Python object to wire format.

93

94

Args:

95

body_value (object): Python object to serialize

96

97

Returns:

98

str or bytes: Serialized representation

99

"""

100

101

def deserialize(self, content):

102

"""

103

Deserialize wire format to Python object.

104

105

Args:

106

content (bytes): Serialized content to deserialize

107

108

Returns:

109

object: Deserialized Python object

110

"""

111

```

112

113

### JSON Data Model

114

115

Handle JSON request and response processing with optional data wrapping.

116

117

```python { .api }

118

class JsonModel(BaseModel):

119

"""Model for JSON request and response processing."""

120

121

def __init__(self, data_wrapper=False):

122

"""

123

Initialize JSON model.

124

125

Args:

126

data_wrapper (bool): Whether to wrap request data in a 'data' field

127

"""

128

129

def request(self, headers, path_params, query_params, body_value):

130

"""

131

Create a JSON request.

132

133

Args:

134

headers (dict): HTTP headers to modify

135

path_params (dict): Parameters for URL path substitution

136

query_params (dict): Query string parameters

137

body_value (object): Request body data to serialize

138

139

Returns:

140

tuple: (headers, path_params, query_params, body) - processed request components

141

"""

142

143

def response(self, resp, content):

144

"""

145

Process a JSON response.

146

147

Args:

148

resp (httplib2.Response): HTTP response object

149

content (bytes): Response body content

150

151

Returns:

152

object: Deserialized JSON response data

153

"""

154

```

155

156

### Raw Data Model

157

158

Handle raw binary request and response data without serialization.

159

160

```python { .api }

161

class RawModel(JsonModel):

162

"""Model for requests that don't return JSON.

163

164

Serializes and de-serializes between JSON and the Python object representation

165

of HTTP request, and returns the raw bytes of the response body.

166

"""

167

168

def request(self, headers, path_params, query_params, body_value):

169

"""

170

Create a raw data request.

171

172

Args:

173

headers (dict): HTTP headers to modify

174

path_params (dict): Parameters for URL path substitution

175

query_params (dict): Query string parameters

176

body_value (bytes or str): Raw request body data

177

178

Returns:

179

tuple: (headers, path_params, query_params, body) - processed request components

180

"""

181

182

def response(self, resp, content):

183

"""

184

Process a raw response.

185

186

Args:

187

resp (httplib2.Response): HTTP response object

188

content (bytes): Response body content

189

190

Returns:

191

bytes: Raw response content

192

"""

193

```

194

195

### Media Data Model

196

197

Handle media requests and responses for file uploads and downloads.

198

199

```python { .api }

200

class MediaModel(JsonModel):

201

"""Model for requests that return Media.

202

203

Serializes and de-serializes between JSON and the Python object representation

204

of HTTP request, and returns the raw bytes of the response body.

205

"""

206

207

def request(self, headers, path_params, query_params, body_value):

208

"""

209

Create a media request.

210

211

Args:

212

headers (dict): HTTP headers to modify

213

path_params (dict): Parameters for URL path substitution

214

query_params (dict): Query string parameters

215

body_value (MediaUpload): Media upload object

216

217

Returns:

218

tuple: (headers, path_params, query_params, body) - processed request components

219

"""

220

221

def response(self, resp, content):

222

"""

223

Process a media response.

224

225

Args:

226

resp (httplib2.Response): HTTP response object

227

content (bytes): Response body content

228

229

Returns:

230

object: Processed media response data

231

"""

232

```

233

234

### Protocol Buffer Model

235

236

Handle Protocol Buffer serialization and deserialization.

237

238

```python { .api }

239

class ProtocolBufferModel(BaseModel):

240

"""Model for protocol buffers.

241

242

Serializes and de-serializes the binary protocol buffer sent in the HTTP

243

request and response bodies.

244

"""

245

246

def __init__(self, protocol_buffer):

247

"""

248

Initialize Protocol Buffer model.

249

250

Args:

251

protocol_buffer: Protocol Buffer message class for serialization

252

"""

253

254

def request(self, headers, path_params, query_params, body_value):

255

"""

256

Create a Protocol Buffer request.

257

258

Args:

259

headers (dict): HTTP headers to modify

260

path_params (dict): Parameters for URL path substitution

261

query_params (dict): Query string parameters

262

body_value (Message): Protocol Buffer message to serialize

263

264

Returns:

265

tuple: (headers, path_params, query_params, body) - processed request components

266

"""

267

268

def response(self, resp, content):

269

"""

270

Process a Protocol Buffer response.

271

272

Args:

273

resp (httplib2.Response): HTTP response object

274

content (bytes): Response body content

275

276

Returns:

277

Message: Deserialized Protocol Buffer message

278

"""

279

```

280

281

### Request Processing Utilities

282

283

Utility functions for request body construction and parameter handling.

284

285

```python { .api }

286

def makepatch(original, modified):

287

"""

288

Create a patch object by comparing two resource states.

289

290

Some methods support PATCH, an efficient way to send updates to a resource.

291

This method allows the easy construction of patch bodies by looking at the

292

differences between a resource before and after it was modified.

293

294

Args:

295

original (object): The original deserialized resource

296

modified (object): The modified deserialized resource

297

298

Returns:

299

object: An object containing only the changes from original to modified

300

"""

301

302

# Module-level debugging flag

303

dump_request_response = False # Boolean flag for enabling request/response logging

304

```

305

306

## Usage Examples

307

308

### Custom JSON Model

309

310

```python

311

from googleapiclient import discovery

312

from googleapiclient.model import JsonModel

313

314

# Create service with custom JSON model

315

json_model = JsonModel(data_wrapper=True)

316

service = discovery.build(

317

'gmail',

318

'v1',

319

credentials=credentials,

320

model=json_model

321

)

322

323

# Requests will wrap data in 'data' field

324

# Responses will be processed as JSON

325

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

326

```

327

328

### Raw Data Model

329

330

```python

331

from googleapiclient.model import RawModel

332

333

# Create service with raw model for binary data

334

raw_model = RawModel()

335

service = discovery.build(

336

'storage',

337

'v1',

338

credentials=credentials,

339

model=raw_model

340

)

341

342

# Responses will be returned as raw bytes

343

object_data = service.objects().get(

344

bucket='my-bucket',

345

object='my-file.bin'

346

).execute()

347

348

print(f"Downloaded {len(object_data)} bytes")

349

```

350

351

### Media Model Integration

352

353

```python

354

from googleapiclient.model import MediaModel

355

from googleapiclient.http import MediaFileUpload

356

357

# Create service with media model

358

media_model = MediaModel()

359

service = discovery.build(

360

'drive',

361

'v3',

362

credentials=credentials,

363

model=media_model

364

)

365

366

# Upload with media model handling

367

media = MediaFileUpload('document.pdf', mimetype='application/pdf')

368

file_metadata = {'name': 'uploaded-document.pdf'}

369

370

file = service.files().create(

371

body=file_metadata,

372

media_body=media

373

).execute()

374

```

375

376

### Protocol Buffer Model

377

378

```python

379

from googleapiclient.model import ProtocolBufferModel

380

import my_protobuf_pb2 # Your protocol buffer definitions

381

382

# Create service with protocol buffer model

383

pb_model = ProtocolBufferModel(my_protobuf_pb2.MyMessage)

384

service = discovery.build(

385

'my-api',

386

'v1',

387

credentials=credentials,

388

model=pb_model

389

)

390

391

# Create protocol buffer message

392

message = my_protobuf_pb2.MyMessage()

393

message.field1 = "value1"

394

message.field2 = 42

395

396

# Send protocol buffer request

397

response = service.my_resource().create(body=message).execute()

398

# Response will be deserialized protocol buffer

399

```

400

401

### Custom Request Body Processing

402

403

```python

404

from googleapiclient.model import makebody

405

406

# Custom request processing

407

def create_custom_request(service, resource_data):

408

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

409

params = {'userId': 'me', 'format': 'json'}

410

411

# Method description from discovery document

412

method_desc = {

413

'parameters': {

414

'userId': {'location': 'path'},

415

'format': {'location': 'query'}

416

}

417

}

418

419

# Create request body

420

processed_headers, processed_body = makebody(

421

headers,

422

params,

423

resource_data,

424

method_desc

425

)

426

427

return processed_headers, processed_body

428

429

# Use custom processing

430

headers, body = create_custom_request(service, {'message': 'Hello World'})

431

```

432

433

### JSON Patch Creation

434

435

```python

436

from googleapiclient.model import makepatch

437

438

# Original and modified data

439

original_message = {

440

'subject': 'Original Subject',

441

'body': 'Original body text',

442

'labels': ['INBOX', 'UNREAD']

443

}

444

445

modified_message = {

446

'subject': 'Updated Subject',

447

'body': 'Original body text', # Unchanged

448

'labels': ['INBOX'] # Removed UNREAD

449

}

450

451

# Create patch

452

patch = makepatch(original_message, modified_message)

453

print(patch)

454

# Output: Patch operations representing the changes

455

456

# Use patch in API request

457

service.users().messages().modify(

458

userId='me',

459

id='message_id',

460

body=patch

461

).execute()

462

```

463

464

### Model Selection Based on Content Type

465

466

```python

467

from googleapiclient.model import JsonModel, RawModel, MediaModel

468

469

def get_model_for_content_type(content_type):

470

"""Select appropriate model based on content type."""

471

472

if content_type.startswith('application/json'):

473

return JsonModel()

474

elif content_type.startswith('image/') or content_type.startswith('video/'):

475

return MediaModel()

476

else:

477

return RawModel()

478

479

# Dynamic model selection

480

content_type = 'application/json'

481

model = get_model_for_content_type(content_type)

482

483

service = discovery.build(

484

'my-api',

485

'v1',

486

credentials=credentials,

487

model=model

488

)

489

```

490

491

### Request and Response Interception

492

493

```python

494

from googleapiclient.model import JsonModel

495

496

class LoggingJsonModel(JsonModel):

497

"""JSON model with request/response logging."""

498

499

def request(self, headers, path_params, query_params, body_value):

500

print(f"Request body: {body_value}")

501

return super().request(headers, path_params, query_params, body_value)

502

503

def response(self, resp, content):

504

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

505

result = super().response(resp, content)

506

print(f"Response data: {result}")

507

return result

508

509

# Use logging model

510

logging_model = LoggingJsonModel()

511

service = discovery.build(

512

'gmail',

513

'v1',

514

credentials=credentials,

515

model=logging_model

516

)

517

518

# All requests and responses will be logged

519

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

520

```