or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

blueprints.mdcli.mdconfiguration.mdcontext-globals.mdcore-application.mdhelpers.mdindex.mdjson-support.mdrequest-response.mdrouting.mdsessions.mdsignals.mdtemplates.mdtesting.md

request-response.mddocs/

0

# Request and Response Handling

1

2

Flask provides Request and Response classes for handling HTTP data. The Request object contains all incoming HTTP data, while the Response object represents the HTTP response sent back to the client.

3

4

## Capabilities

5

6

### Request Object

7

8

The Request object contains all data from the incoming HTTP request.

9

10

```python { .api }

11

class Request:

12

# HTTP method and URL information

13

method: str # HTTP method (GET, POST, etc.)

14

url: str # Complete URL

15

base_url: str # URL without query string

16

url_root: str # Root URL (scheme + host + port)

17

path: str # URL path

18

query_string: bytes # Raw query string

19

full_path: str # Path + query string

20

21

# Request data

22

args: ImmutableMultiDict # URL query parameters

23

form: ImmutableMultiDict # Form data from POST/PUT

24

files: ImmutableMultiDict # Uploaded files

25

values: ImmutableMultiDict # Combined args and form data

26

json: Any # Parsed JSON data (if Content-Type is JSON)

27

data: bytes # Raw request body data

28

29

# Headers and metadata

30

headers: EnvironHeaders # HTTP headers

31

cookies: ImmutableMultiDict # Request cookies

32

content_type: str | None # Content-Type header

33

content_length: int | None # Content-Length header

34

mimetype: str # Main content type without parameters

35

36

# Remote client information

37

remote_addr: str | None # Client IP address

38

remote_user: str | None # Remote user (if authenticated)

39

40

# Flask-specific attributes

41

endpoint: str | None # Matched endpoint name

42

view_args: dict[str, Any] | None # URL rule variables

43

url_rule: Rule | None # Matched URL rule

44

blueprint: str | None # Blueprint name

45

46

# Environment and context

47

environ: dict # WSGI environment

48

shallow: bool # Whether request was created with shallow=True

49

50

def get_json(

51

self,

52

force: bool = False,

53

silent: bool = False,

54

cache: bool = True

55

) -> Any:

56

"""

57

Parse request data as JSON.

58

59

Args:

60

force: Parse even if Content-Type is not JSON

61

silent: Return None on parse errors instead of raising

62

cache: Cache parsed JSON for subsequent calls

63

64

Returns:

65

Parsed JSON data or None

66

67

Raises:

68

BadRequest: If JSON parsing fails and silent=False

69

"""

70

71

def get_data(self, cache: bool = True, as_text: bool = False, parse_form_data: bool = False) -> bytes | str:

72

"""

73

Get raw request body data.

74

75

Args:

76

cache: Cache data for subsequent calls

77

as_text: Return data as text string

78

parse_form_data: Parse form data from body

79

80

Returns:

81

Request body as bytes or string

82

"""

83

84

@property

85

def is_json(self) -> bool:

86

"""Check if request has JSON content type."""

87

88

@property

89

def is_secure(self) -> bool:

90

"""Check if request was made over HTTPS."""

91

92

@property

93

def is_xhr(self) -> bool:

94

"""Check if request was made via XMLHttpRequest (deprecated)."""

95

```

96

97

### Response Object

98

99

The Response object represents the HTTP response sent to the client.

100

101

```python { .api }

102

class Response:

103

def __init__(

104

self,

105

response: Any = None,

106

status: int | str | None = None,

107

headers: dict | list | None = None,

108

mimetype: str | None = None,

109

content_type: str | None = None,

110

direct_passthrough: bool = False

111

):

112

"""

113

Create a Response object.

114

115

Args:

116

response: Response data (string, bytes, or iterable)

117

status: HTTP status code or phrase

118

headers: Response headers

119

mimetype: Response MIME type

120

content_type: Complete Content-Type header

121

direct_passthrough: Pass response directly to WSGI server

122

"""

123

124

# Response data and status

125

data: bytes # Response body as bytes

126

status: str # HTTP status line

127

status_code: int # HTTP status code

128

129

# Headers

130

headers: Headers # Response headers

131

content_type: str | None # Content-Type header

132

content_length: int | None # Content-Length header

133

mimetype: str # Main content type

134

135

# Caching and cookies

136

cache_control: ResponseCacheControl # Cache-Control header

137

expires: datetime | None # Expires header

138

last_modified: datetime | None # Last-Modified header

139

etag: str | None # ETag header

140

vary: HeaderSet # Vary header

141

142

def set_cookie(

143

self,

144

key: str,

145

value: str = '',

146

max_age: int | None = None,

147

expires: datetime | str | None = None,

148

path: str | None = '/',

149

domain: str | None = None,

150

secure: bool = False,

151

httponly: bool = False,

152

samesite: str | None = None

153

) -> None:

154

"""

155

Set a cookie on the response.

156

157

Args:

158

key: Cookie name

159

value: Cookie value

160

max_age: Cookie max age in seconds

161

expires: Cookie expiration date

162

path: Cookie path

163

domain: Cookie domain

164

secure: Require HTTPS for cookie

165

httponly: Prevent JavaScript access

166

samesite: SameSite attribute ('Strict', 'Lax', or 'None')

167

"""

168

169

def delete_cookie(

170

self,

171

key: str,

172

path: str | None = '/',

173

domain: str | None = None,

174

secure: bool = False,

175

httponly: bool = False,

176

samesite: str | None = None

177

) -> None:

178

"""

179

Delete a cookie by setting it to expire immediately.

180

181

Args:

182

key: Cookie name to delete

183

path: Cookie path (must match original)

184

domain: Cookie domain (must match original)

185

secure: Secure flag (must match original)

186

httponly: HttpOnly flag (must match original)

187

samesite: SameSite flag (must match original)

188

"""

189

190

@property

191

def is_json(self) -> bool:

192

"""Check if response has JSON content type."""

193

194

def get_json(self, force: bool = False, silent: bool = False, cache: bool = True) -> Any:

195

"""

196

Parse response data as JSON.

197

198

Args:

199

force: Parse even if Content-Type is not JSON

200

silent: Return None on parse errors

201

cache: Cache parsed JSON

202

203

Returns:

204

Parsed JSON data or None

205

"""

206

```

207

208

### Response Creation Helpers

209

210

Functions for creating different types of responses.

211

212

```python { .api }

213

def make_response(*args) -> Response:

214

"""

215

Create a Response object from various inputs.

216

217

Args:

218

*args: Response data, status, headers in various combinations

219

220

Returns:

221

Response object

222

223

Examples:

224

make_response('Hello')

225

make_response('Hello', 200)

226

make_response('Error', 404, {'Content-Type': 'text/plain'})

227

make_response(('Hello', 200, {'X-Custom': 'value'}))

228

"""

229

```

230

231

## Usage Examples

232

233

### Accessing Request Data

234

235

```python

236

from flask import Flask, request, jsonify

237

238

app = Flask(__name__)

239

240

@app.route('/info')

241

def request_info():

242

return {

243

'method': request.method,

244

'url': request.url,

245

'path': request.path,

246

'args': dict(request.args),

247

'headers': dict(request.headers),

248

'remote_addr': request.remote_addr,

249

'is_secure': request.is_secure,

250

'is_json': request.is_json

251

}

252

253

@app.route('/query')

254

def query_params():

255

# Get single value

256

name = request.args.get('name', 'Unknown')

257

258

# Get multiple values for same key

259

tags = request.args.getlist('tag')

260

261

# Get with type conversion

262

page = request.args.get('page', 1, type=int)

263

264

return {

265

'name': name,

266

'tags': tags,

267

'page': page

268

}

269

```

270

271

### Handling Form Data

272

273

```python

274

from flask import Flask, request, render_template

275

276

app = Flask(__name__)

277

278

@app.route('/form', methods=['GET', 'POST'])

279

def form_handler():

280

if request.method == 'GET':

281

return render_template('form.html')

282

283

# Handle form submission

284

username = request.form.get('username')

285

email = request.form.get('email')

286

287

# Handle checkboxes (multiple values)

288

interests = request.form.getlist('interests')

289

290

# Validate required fields

291

if not username or not email:

292

return 'Username and email are required', 400

293

294

return f'Hello {username}! Email: {email}, Interests: {interests}'

295

296

@app.route('/upload', methods=['POST'])

297

def file_upload():

298

if 'file' not in request.files:

299

return 'No file uploaded', 400

300

301

file = request.files['file']

302

if file.filename == '':

303

return 'No file selected', 400

304

305

if file:

306

# Save file

307

filename = secure_filename(file.filename)

308

file.save(os.path.join('uploads', filename))

309

return f'File {filename} uploaded successfully'

310

```

311

312

### JSON Request Handling

313

314

```python

315

from flask import Flask, request, jsonify

316

317

app = Flask(__name__)

318

319

@app.route('/api/user', methods=['POST'])

320

def create_user():

321

# Check if request contains JSON

322

if not request.is_json:

323

return {'error': 'Content-Type must be application/json'}, 400

324

325

# Get JSON data

326

data = request.get_json()

327

328

# Validate required fields

329

required_fields = ['name', 'email']

330

for field in required_fields:

331

if field not in data:

332

return {'error': f'Missing field: {field}'}, 400

333

334

# Process user creation

335

user = {

336

'id': 123,

337

'name': data['name'],

338

'email': data['email'],

339

'created': '2023-01-01T00:00:00Z'

340

}

341

342

return jsonify(user), 201

343

344

@app.route('/api/data', methods=['PUT'])

345

def update_data():

346

try:

347

data = request.get_json(force=True)

348

except Exception:

349

return {'error': 'Invalid JSON'}, 400

350

351

return {'message': 'Data updated', 'received': data}

352

```

353

354

### Creating Custom Responses

355

356

```python

357

from flask import Flask, make_response, jsonify, render_template

358

from datetime import datetime, timedelta

359

360

app = Flask(__name__)

361

362

@app.route('/custom')

363

def custom_response():

364

# Create response with custom headers

365

response = make_response('Custom response content')

366

response.headers['X-Custom-Header'] = 'Custom Value'

367

response.status_code = 200

368

return response

369

370

@app.route('/json-custom')

371

def json_custom():

372

data = {'message': 'Hello', 'timestamp': datetime.now().isoformat()}

373

response = make_response(jsonify(data))

374

response.headers['X-API-Version'] = '1.0'

375

return response

376

377

@app.route('/template-custom')

378

def template_custom():

379

html = render_template('page.html', title='Custom Page')

380

response = make_response(html)

381

response.headers['X-Generated'] = 'Flask'

382

return response

383

384

@app.route('/download')

385

def download_file():

386

data = 'File content here'

387

response = make_response(data)

388

response.headers['Content-Type'] = 'application/octet-stream'

389

response.headers['Content-Disposition'] = 'attachment; filename=data.txt'

390

return response

391

```

392

393

### Cookie Handling

394

395

```python

396

from flask import Flask, request, make_response

397

from datetime import datetime, timedelta

398

399

app = Flask(__name__)

400

401

@app.route('/set-cookie')

402

def set_cookie():

403

response = make_response('Cookie set!')

404

405

# Simple cookie

406

response.set_cookie('username', 'john')

407

408

# Cookie with expiration

409

expires = datetime.now() + timedelta(days=30)

410

response.set_cookie('session_id', 'abc123', expires=expires)

411

412

# Secure cookie

413

response.set_cookie(

414

'secure_token',

415

'secret_value',

416

secure=True,

417

httponly=True,

418

samesite='Strict'

419

)

420

421

return response

422

423

@app.route('/get-cookie')

424

def get_cookie():

425

username = request.cookies.get('username', 'Guest')

426

session_id = request.cookies.get('session_id')

427

428

return {

429

'username': username,

430

'session_id': session_id,

431

'all_cookies': dict(request.cookies)

432

}

433

434

@app.route('/delete-cookie')

435

def delete_cookie():

436

response = make_response('Cookie deleted!')

437

response.delete_cookie('username')

438

return response

439

```

440

441

### Response Headers and Caching

442

443

```python

444

from flask import Flask, make_response

445

from datetime import datetime, timedelta

446

447

app = Flask(__name__)

448

449

@app.route('/cached')

450

def cached_response():

451

response = make_response('This response is cached')

452

453

# Set cache headers

454

response.cache_control.max_age = 3600 # 1 hour

455

response.cache_control.public = True

456

457

# Set ETag for conditional requests

458

response.set_etag('resource-v1')

459

460

# Set Last-Modified

461

response.last_modified = datetime.now()

462

463

return response

464

465

@app.route('/no-cache')

466

def no_cache_response():

467

response = make_response('This response is not cached')

468

469

# Prevent caching

470

response.cache_control.no_cache = True

471

response.cache_control.no_store = True

472

response.cache_control.must_revalidate = True

473

474

# Set expiration in the past

475

response.expires = datetime.now() - timedelta(hours=1)

476

477

return response

478

479

@app.route('/api/cors')

480

def cors_response():

481

response = make_response({'message': 'CORS enabled'})

482

483

# CORS headers

484

response.headers['Access-Control-Allow-Origin'] = '*'

485

response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'

486

response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'

487

488

return response

489

```

490

491

### Error Responses

492

493

```python

494

from flask import Flask, request, jsonify, make_response

495

496

app = Flask(__name__)

497

498

@app.route('/api/users/<int:user_id>')

499

def get_user(user_id):

500

# Simulate user lookup

501

if user_id <= 0:

502

return {'error': 'Invalid user ID'}, 400

503

504

if user_id > 1000:

505

return {'error': 'User not found'}, 404

506

507

return {'id': user_id, 'name': f'User {user_id}'}

508

509

@app.errorhandler(400)

510

def bad_request(error):

511

return make_response(

512

jsonify({'error': 'Bad Request', 'message': str(error)}),

513

400,

514

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

515

)

516

517

@app.errorhandler(404)

518

def not_found(error):

519

if request.path.startswith('/api/'):

520

# JSON error for API routes

521

return jsonify({'error': 'Not Found'}), 404

522

else:

523

# HTML error for web routes

524

return render_template('404.html'), 404

525

526

@app.errorhandler(500)

527

def internal_error(error):

528

response = make_response('Internal Server Error', 500)

529

response.headers['X-Error-ID'] = 'ERR-12345'

530

return response

531

```