or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

blueprints.mdconfiguration.mdcore-application.mdexceptions.mdindex.mdmiddleware-signals.mdrequest-response.mdserver-deployment.mdwebsockets.md

request-response.mddocs/

0

# Request and Response Handling

1

2

Comprehensive request and response objects for handling HTTP communications in Sanic applications. The Request object provides access to all incoming request data, while response functions create properly formatted HTTP responses.

3

4

## Capabilities

5

6

### Request Object

7

8

The Request object contains all information about the incoming HTTP request, including headers, body data, query parameters, and metadata.

9

10

```python { .api }

11

class Request:

12

"""HTTP request object containing request data and metadata."""

13

14

@property

15

def app(self):

16

"""Reference to the Sanic application instance."""

17

18

@property

19

def body(self) -> bytes:

20

"""Raw request body as bytes."""

21

22

@property

23

def content_type(self) -> str:

24

"""Request content type from headers."""

25

26

@property

27

def json(self):

28

"""

29

Request body parsed as JSON.

30

31

Returns:

32

Parsed JSON data or None if not JSON

33

34

Raises:

35

InvalidUsage: If JSON is malformed

36

"""

37

38

@property

39

def form(self) -> dict:

40

"""

41

Form data from request body.

42

43

Returns:

44

Dictionary of form fields

45

"""

46

47

@property

48

def files(self) -> dict:

49

"""

50

Uploaded files from multipart form data.

51

52

Returns:

53

Dictionary of File objects

54

"""

55

56

@property

57

def args(self) -> dict:

58

"""

59

Query string arguments.

60

61

Returns:

62

Dictionary of query parameters

63

"""

64

65

@property

66

def raw_args(self) -> dict:

67

"""Raw query string arguments without processing."""

68

69

@property

70

def query_args(self) -> list:

71

"""

72

Query arguments as list of tuples.

73

74

Returns:

75

List of (key, value) tuples

76

"""

77

78

@property

79

def headers(self):

80

"""

81

Request headers.

82

83

Returns:

84

Header dictionary

85

"""

86

87

@property

88

def method(self) -> str:

89

"""HTTP method (GET, POST, etc.)."""

90

91

@property

92

def ip(self) -> str:

93

"""Client IP address."""

94

95

@property

96

def forwarded(self) -> dict:

97

"""Forwarded headers information."""

98

99

@property

100

def remote_addr(self) -> str:

101

"""Remote client address."""

102

103

@property

104

def scheme(self) -> str:

105

"""Request scheme (http or https)."""

106

107

@property

108

def host(self) -> str:

109

"""Request host header."""

110

111

@property

112

def path(self) -> str:

113

"""Request path without query string."""

114

115

@property

116

def query_string(self) -> str:

117

"""Raw query string."""

118

119

@property

120

def url(self) -> str:

121

"""Complete request URL."""

122

123

@property

124

def token(self) -> str:

125

"""Authorization token from Authorization header."""

126

127

@property

128

def match_info(self) -> dict:

129

"""Route match information and parameters."""

130

131

@property

132

def stream(self):

133

"""Request stream for handling large uploads."""

134

135

@property

136

def ctx(self):

137

"""Request context object for storing custom data."""

138

139

def get_args(

140

self,

141

key: str,

142

default=None,

143

type=str

144

):

145

"""

146

Get query argument with type conversion.

147

148

Parameters:

149

- key: Argument name

150

- default: Default value if not found

151

- type: Type conversion function

152

153

Returns:

154

Converted argument value

155

"""

156

157

def get_query_args(self, key: str, default=None):

158

"""Alias for get_args method."""

159

160

def get_form(self, key: str, default=None):

161

"""

162

Get form field value.

163

164

Parameters:

165

- key: Form field name

166

- default: Default value if not found

167

168

Returns:

169

Form field value

170

"""

171

172

def get_files(self, key: str, default=None):

173

"""

174

Get uploaded file.

175

176

Parameters:

177

- key: File field name

178

- default: Default value if not found

179

180

Returns:

181

File object or default

182

"""

183

184

def url_for(self, view_name: str, **kwargs) -> str:

185

"""

186

Generate URL for named route.

187

188

Parameters:

189

- view_name: Route name

190

- **kwargs: URL parameters

191

192

Returns:

193

Generated URL

194

"""

195

196

async def receive_body(self) -> bytes:

197

"""

198

Receive request body asynchronously.

199

200

Returns:

201

Request body bytes

202

"""

203

```

204

205

### Response Functions

206

207

Factory functions for creating HTTP responses with different content types and behaviors.

208

209

```python { .api }

210

def json(

211

body: Any,

212

status: int = 200,

213

headers: Optional[dict[str, str]] = None,

214

content_type: str = "application/json",

215

dumps: Optional[Callable[..., AnyStr]] = None,

216

**kwargs: Any,

217

):

218

"""

219

Create JSON response.

220

221

Parameters:

222

- body: Data to serialize as JSON

223

- status: HTTP status code

224

- headers: Additional headers

225

- content_type: Response content type

226

- dumps: Custom JSON serializer

227

228

Returns:

229

HTTPResponse with JSON content

230

"""

231

232

def text(

233

body: str,

234

status: int = 200,

235

headers: dict = None,

236

content_type: str = "text/plain; charset=utf-8",

237

**kwargs

238

):

239

"""

240

Create plain text response.

241

242

Parameters:

243

- body: Text content

244

- status: HTTP status code

245

- headers: Additional headers

246

- content_type: Response content type

247

248

Returns:

249

HTTPResponse with text content

250

"""

251

252

def html(

253

body: str,

254

status: int = 200,

255

headers: dict = None,

256

**kwargs

257

):

258

"""

259

Create HTML response.

260

261

Parameters:

262

- body: HTML content

263

- status: HTTP status code

264

- headers: Additional headers

265

266

Returns:

267

HTTPResponse with HTML content

268

"""

269

270

def raw(

271

body: bytes,

272

status: int = 200,

273

headers: dict = None,

274

content_type: str = "application/octet-stream",

275

**kwargs

276

):

277

"""

278

Create raw bytes response.

279

280

Parameters:

281

- body: Raw bytes content

282

- status: HTTP status code

283

- headers: Additional headers

284

- content_type: Response content type

285

286

Returns:

287

HTTPResponse with raw content

288

"""

289

290

def redirect(

291

to: str,

292

status: int = 302,

293

headers: dict = None,

294

**kwargs

295

):

296

"""

297

Create redirect response.

298

299

Parameters:

300

- to: Redirect URL

301

- status: HTTP redirect status code (301, 302, 303, 307, 308)

302

- headers: Additional headers

303

304

Returns:

305

HTTPResponse with redirect

306

"""

307

308

def file(

309

location: str,

310

status: int = 200,

311

mime_type: str = None,

312

headers: dict = None,

313

filename: str = None,

314

**kwargs

315

):

316

"""

317

Create file response.

318

319

Parameters:

320

- location: File path

321

- status: HTTP status code

322

- mime_type: File MIME type

323

- headers: Additional headers

324

- filename: Download filename

325

326

Returns:

327

FileResponse for serving files

328

"""

329

330

def empty(

331

status: int = 204,

332

headers: Optional[dict[str, str]] = None,

333

):

334

"""

335

Create empty response.

336

337

Parameters:

338

- status: HTTP status code

339

- headers: Additional headers

340

341

Returns:

342

HTTPResponse with no content

343

"""

344

```

345

346

### HTTPResponse Class

347

348

The base response class that all response functions return, providing response manipulation and sending capabilities.

349

350

```python { .api }

351

class HTTPResponse:

352

"""HTTP response object."""

353

354

def __init__(

355

self,

356

body: bytes = None,

357

status: int = 200,

358

headers: dict = None,

359

content_type: str = None,

360

**kwargs

361

):

362

"""

363

Initialize HTTP response.

364

365

Parameters:

366

- body: Response body

367

- status: HTTP status code

368

- headers: Response headers

369

- content_type: Content type header

370

"""

371

372

@property

373

def body(self) -> bytes:

374

"""Response body as bytes."""

375

376

@property

377

def status(self) -> int:

378

"""HTTP status code."""

379

380

@property

381

def content_type(self) -> str:

382

"""Response content type."""

383

384

@property

385

def headers(self):

386

"""Response headers object."""

387

388

@property

389

def cookies(self):

390

"""Response cookies."""

391

392

async def send(

393

self,

394

data: bytes = None,

395

end_stream: bool = None

396

):

397

"""

398

Send response data.

399

400

Parameters:

401

- data: Data to send

402

- end_stream: Whether to end the stream

403

"""

404

405

def stream(

406

self,

407

request,

408

write_buffer_size: int = 4096,

409

**kwargs

410

):

411

"""

412

Stream response data.

413

414

Parameters:

415

- request: Request object

416

- write_buffer_size: Buffer size for writing

417

"""

418

```

419

420

### Streaming Responses

421

422

Handle large responses and real-time data streaming with streaming response capabilities.

423

424

```python { .api }

425

class StreamingHTTPResponse(HTTPResponse):

426

"""Streaming HTTP response for large content."""

427

428

def __init__(

429

self,

430

streaming_fn,

431

status: int = 200,

432

headers: dict = None,

433

content_type: str = "text/plain",

434

**kwargs

435

):

436

"""

437

Initialize streaming response.

438

439

Parameters:

440

- streaming_fn: Async function that yields data

441

- status: HTTP status code

442

- headers: Response headers

443

- content_type: Content type

444

"""

445

446

class ResponseStream:

447

"""Helper for streaming responses."""

448

449

async def write(self, data: bytes):

450

"""

451

Write data to stream.

452

453

Parameters:

454

- data: Data bytes to write

455

"""

456

457

async def end(self):

458

"""End the stream."""

459

```

460

461

### File Uploads

462

463

Handle uploaded files through the request.files interface.

464

465

```python { .api }

466

class File:

467

"""Uploaded file object."""

468

469

@property

470

def name(self) -> str:

471

"""Original filename."""

472

473

@property

474

def type(self) -> str:

475

"""File content type."""

476

477

@property

478

def body(self) -> bytes:

479

"""File content as bytes."""

480

481

def save(self, location: str):

482

"""

483

Save file to disk.

484

485

Parameters:

486

- location: Save path

487

"""

488

```

489

490

## Usage Examples

491

492

### Request Data Access

493

494

```python

495

from sanic import Sanic

496

from sanic.response import json

497

498

app = Sanic("MyApp")

499

500

@app.route("/api/data", methods=["POST"])

501

async def handle_data(request):

502

# Access different types of request data

503

json_data = request.json

504

form_data = request.form

505

files = request.files

506

query_params = request.args

507

headers = request.headers

508

509

# Process uploaded files

510

if "upload" in files:

511

uploaded_file = files["upload"]

512

uploaded_file.save(f"/uploads/{uploaded_file.name}")

513

514

return json({

515

"received_json": json_data,

516

"form_fields": list(form_data.keys()),

517

"query_params": dict(query_params),

518

"content_type": request.content_type,

519

"client_ip": request.ip

520

})

521

```

522

523

### Response Generation

524

525

```python

526

from sanic.response import json, text, html, redirect, file

527

528

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

529

async def get_user(request, user_id):

530

user = await fetch_user(user_id)

531

if not user:

532

return json({"error": "User not found"}, status=404)

533

return json({"user": user})

534

535

@app.route("/download/<filename>")

536

async def download_file(request, filename):

537

file_path = f"/files/{filename}"

538

return await file(file_path, filename=filename)

539

540

@app.route("/redirect")

541

async def redirect_example(request):

542

return redirect("/new-location", status=301)

543

544

@app.route("/streaming")

545

async def streaming_example(request):

546

async def generate_data():

547

for i in range(1000):

548

yield f"data chunk {i}\n".encode()

549

550

return StreamingHTTPResponse(generate_data)

551

```

552

553

### Custom Response Headers and Cookies

554

555

```python

556

from sanic.response import json

557

558

@app.route("/api/login", methods=["POST"])

559

async def login(request):

560

# Authenticate user

561

user = await authenticate(request.json)

562

563

response = json({"user": user["id"]})

564

565

# Set custom headers

566

response.headers["X-Custom-Header"] = "custom-value"

567

568

# Set cookies

569

response.cookies["session_token"] = user["token"]

570

response.cookies["session_token"]["httponly"] = True

571

response.cookies["session_token"]["secure"] = True

572

response.cookies["session_token"]["max-age"] = 3600

573

574

return response

575

```

576

577

### Request Streaming

578

579

```python

580

@app.route("/upload-large", methods=["POST"], stream=True)

581

async def upload_large_file(request):

582

"""Handle large file uploads with streaming."""

583

584

async def save_chunks():

585

with open("/tmp/uploaded_file", "wb") as f:

586

async for body in request.stream:

587

f.write(body)

588

589

await save_chunks()

590

return json({"status": "uploaded"})

591

```