or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-responses.mdapi-routing.mdbackground-tasks.mdcore-application.mddata-utilities.mddependency-injection.mdexception-handling.mdindex.mdmiddleware.mdrequest-parameters.mdrequest-response.mdsecurity-authentication.mdstatic-templating.mdtesting.mdwebsocket-support.md

advanced-responses.mddocs/

0

# Advanced Response Types

1

2

FastAPI provides a comprehensive set of response classes for different content types and use cases, including high-performance JSON responses, HTML responses, file serving, streaming, and redirects. These response types enable efficient content delivery optimized for specific scenarios and client requirements.

3

4

## Capabilities

5

6

### High-Performance JSON Responses

7

8

Ultra-fast JSON response classes using optimized JSON libraries for maximum performance.

9

10

```python { .api }

11

class UJSONResponse(Response):

12

def __init__(

13

self,

14

content: Any = None,

15

status_code: int = 200,

16

headers: dict = None,

17

media_type: str = "application/json",

18

background: BackgroundTask = None,

19

) -> None:

20

"""

21

JSON response using ujson for high performance.

22

23

Parameters:

24

- content: Data to serialize as JSON

25

- status_code: HTTP status code

26

- headers: Additional HTTP headers

27

- media_type: Content type header

28

- background: Background task to run after response

29

"""

30

31

class ORJSONResponse(Response):

32

def __init__(

33

self,

34

content: Any = None,

35

status_code: int = 200,

36

headers: dict = None,

37

media_type: str = "application/json",

38

background: BackgroundTask = None,

39

) -> None:

40

"""

41

JSON response using orjson for maximum performance.

42

43

Parameters:

44

- content: Data to serialize as JSON

45

- status_code: HTTP status code

46

- headers: Additional HTTP headers

47

- media_type: Content type header

48

- background: Background task to run after response

49

"""

50

```

51

52

### HTML and Plain Text Responses

53

54

Response classes for serving HTML content and plain text.

55

56

```python { .api }

57

class HTMLResponse(Response):

58

def __init__(

59

self,

60

content: str = "",

61

status_code: int = 200,

62

headers: dict = None,

63

media_type: str = "text/html",

64

background: BackgroundTask = None,

65

) -> None:

66

"""

67

HTML response for serving HTML content.

68

69

Parameters:

70

- content: HTML content string

71

- status_code: HTTP status code

72

- headers: Additional HTTP headers

73

- media_type: Content type header

74

- background: Background task to run after response

75

"""

76

77

class PlainTextResponse(Response):

78

def __init__(

79

self,

80

content: str = "",

81

status_code: int = 200,

82

headers: dict = None,

83

media_type: str = "text/plain",

84

background: BackgroundTask = None,

85

) -> None:

86

"""

87

Plain text response.

88

89

Parameters:

90

- content: Plain text content string

91

- status_code: HTTP status code

92

- headers: Additional HTTP headers

93

- media_type: Content type header

94

- background: Background task to run after response

95

"""

96

```

97

98

### Redirect Responses

99

100

Response class for HTTP redirects with configurable status codes.

101

102

```python { .api }

103

class RedirectResponse(Response):

104

def __init__(

105

self,

106

url: str,

107

status_code: int = 307,

108

headers: dict = None,

109

background: BackgroundTask = None,

110

) -> None:

111

"""

112

HTTP redirect response.

113

114

Parameters:

115

- url: Target URL for redirect

116

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

117

- headers: Additional HTTP headers

118

- background: Background task to run after response

119

"""

120

```

121

122

### File and Streaming Responses

123

124

Response classes for serving files and streaming large content.

125

126

```python { .api }

127

class FileResponse(Response):

128

def __init__(

129

self,

130

path: str,

131

status_code: int = 200,

132

headers: dict = None,

133

media_type: str = None,

134

filename: str = None,

135

background: BackgroundTask = None,

136

) -> None:

137

"""

138

File download response.

139

140

Parameters:

141

- path: File system path to the file

142

- status_code: HTTP status code

143

- headers: Additional HTTP headers

144

- media_type: Content type (auto-detected if None)

145

- filename: Download filename (Content-Disposition header)

146

- background: Background task to run after response

147

"""

148

149

class StreamingResponse(Response):

150

def __init__(

151

self,

152

content: Iterator[Any],

153

status_code: int = 200,

154

headers: dict = None,

155

media_type: str = None,

156

background: BackgroundTask = None,

157

) -> None:

158

"""

159

Streaming response for large content.

160

161

Parameters:

162

- content: Iterator yielding content chunks

163

- status_code: HTTP status code

164

- headers: Additional HTTP headers

165

- media_type: Content type header

166

- background: Background task to run after response

167

"""

168

```

169

170

## Usage Examples

171

172

### High-Performance JSON Responses

173

174

```python

175

from fastapi import FastAPI

176

from fastapi.responses import UJSONResponse, ORJSONResponse

177

import time

178

179

app = FastAPI()

180

181

# Large dataset for performance comparison

182

large_data = {

183

"users": [

184

{"id": i, "name": f"User {i}", "score": i * 1.5}

185

for i in range(10000)

186

],

187

"timestamp": time.time(),

188

"metadata": {"total": 10000, "version": "1.0"}

189

}

190

191

@app.get("/data/ujson", response_class=UJSONResponse)

192

def get_data_ujson():

193

"""Return large dataset using ujson for faster serialization."""

194

return large_data

195

196

@app.get("/data/orjson", response_class=ORJSONResponse)

197

def get_data_orjson():

198

"""Return large dataset using orjson for maximum performance."""

199

return large_data

200

201

# Set as default response class for entire app

202

app_with_orjson = FastAPI(default_response_class=ORJSONResponse)

203

204

@app_with_orjson.get("/fast")

205

def fast_endpoint():

206

return {"message": "This uses ORJSONResponse by default"}

207

```

208

209

### HTML Responses

210

211

```python

212

from fastapi import FastAPI, Request

213

from fastapi.responses import HTMLResponse

214

215

app = FastAPI()

216

217

@app.get("/", response_class=HTMLResponse)

218

def home():

219

html_content = """

220

<!DOCTYPE html>

221

<html>

222

<head>

223

<title>FastAPI HTML Response</title>

224

<style>

225

body { font-family: Arial, sans-serif; margin: 40px; }

226

.header { color: #2c3e50; }

227

</style>

228

</head>

229

<body>

230

<h1 class="header">Welcome to FastAPI</h1>

231

<p>This is a direct HTML response.</p>

232

<ul>

233

<li><a href="/api/users">API Users</a></li>

234

<li><a href="/api/docs">API Documentation</a></li>

235

</ul>

236

</body>

237

</html>

238

"""

239

return HTMLResponse(content=html_content, status_code=200)

240

241

@app.get("/dynamic/{name}", response_class=HTMLResponse)

242

def dynamic_page(name: str):

243

html_content = f"""

244

<!DOCTYPE html>

245

<html>

246

<head>

247

<title>Hello {name}</title>

248

</head>

249

<body>

250

<h1>Hello, {name}!</h1>

251

<p>This page was generated dynamically.</p>

252

<a href="/">Back to Home</a>

253

</body>

254

</html>

255

"""

256

return HTMLResponse(content=html_content)

257

258

@app.get("/error-page", response_class=HTMLResponse)

259

def error_page():

260

html_content = """

261

<html>

262

<body>

263

<h1>Something went wrong</h1>

264

<p>Please try again later.</p>

265

</body>

266

</html>

267

"""

268

return HTMLResponse(content=html_content, status_code=500)

269

```

270

271

### Redirect Responses

272

273

```python

274

from fastapi import FastAPI, Form

275

from fastapi.responses import RedirectResponse

276

277

app = FastAPI()

278

279

@app.get("/old-url")

280

def old_endpoint():

281

# Permanent redirect (301)

282

return RedirectResponse(url="/new-url", status_code=301)

283

284

@app.get("/new-url")

285

def new_endpoint():

286

return {"message": "This is the new endpoint"}

287

288

@app.post("/login")

289

def login(username: str = Form(...), password: str = Form(...)):

290

# Simulate authentication

291

if username == "admin" and password == "secret":

292

# Temporary redirect after successful login (307)

293

return RedirectResponse(url="/dashboard", status_code=307)

294

else:

295

# Redirect back to login with error

296

return RedirectResponse(url="/login?error=invalid", status_code=303)

297

298

@app.get("/dashboard")

299

def dashboard():

300

return {"message": "Welcome to the dashboard"}

301

302

@app.get("/external-redirect")

303

def external_redirect():

304

# Redirect to external URL

305

return RedirectResponse(url="https://fastapi.tiangolo.com/")

306

307

# Conditional redirects

308

@app.get("/redirect/{target}")

309

def conditional_redirect(target: str):

310

redirect_map = {

311

"docs": "/docs",

312

"redoc": "/redoc",

313

"github": "https://github.com/tiangolo/fastapi",

314

"home": "/"

315

}

316

317

if target in redirect_map:

318

return RedirectResponse(url=redirect_map[target])

319

else:

320

return RedirectResponse(url="/404")

321

```

322

323

### File Responses

324

325

```python

326

from fastapi import FastAPI, HTTPException

327

from fastapi.responses import FileResponse

328

import os

329

from pathlib import Path

330

331

app = FastAPI()

332

333

@app.get("/download/{filename}")

334

def download_file(filename: str):

335

file_path = Path("files") / filename

336

337

if not file_path.exists():

338

raise HTTPException(status_code=404, detail="File not found")

339

340

return FileResponse(

341

path=str(file_path),

342

filename=filename,

343

media_type='application/octet-stream'

344

)

345

346

@app.get("/image/{filename}")

347

def serve_image(filename: str):

348

file_path = Path("images") / filename

349

350

if not file_path.exists():

351

raise HTTPException(status_code=404, detail="Image not found")

352

353

# Auto-detect media type based on file extension

354

return FileResponse(path=str(file_path))

355

356

@app.get("/report/pdf")

357

def download_report():

358

return FileResponse(

359

path="reports/monthly_report.pdf",

360

filename="monthly_report.pdf",

361

media_type="application/pdf"

362

)

363

364

@app.get("/export/csv")

365

def export_data():

366

# Assume CSV file is generated elsewhere

367

return FileResponse(

368

path="exports/data.csv",

369

filename="exported_data.csv",

370

media_type="text/csv",

371

headers={"Custom-Header": "Export-Data"}

372

)

373

```

374

375

### Streaming Responses

376

377

```python

378

from fastapi import FastAPI

379

from fastapi.responses import StreamingResponse

380

import json

381

import time

382

from typing import Iterator

383

384

app = FastAPI()

385

386

def generate_large_csv() -> Iterator[str]:

387

"""Generate large CSV data as iterator."""

388

yield "id,name,email,created_at\n"

389

for i in range(100000):

390

yield f"{i},User{i},user{i}@example.com,2024-01-{(i % 30) + 1:02d}\n"

391

392

@app.get("/export/large-csv")

393

def export_large_csv():

394

return StreamingResponse(

395

generate_large_csv(),

396

media_type="text/csv",

397

headers={"Content-Disposition": "attachment; filename=large_data.csv"}

398

)

399

400

def generate_json_stream() -> Iterator[bytes]:

401

"""Generate streaming JSON response."""

402

yield b'{"data": ['

403

for i in range(1000):

404

if i > 0:

405

yield b','

406

data = {"id": i, "value": f"item_{i}"}

407

yield json.dumps(data).encode("utf-8")

408

yield b']}'

409

410

@app.get("/stream/json")

411

def stream_json():

412

return StreamingResponse(

413

generate_json_stream(),

414

media_type="application/json"

415

)

416

417

def generate_server_sent_events() -> Iterator[str]:

418

"""Generate Server-Sent Events stream."""

419

for i in range(10):

420

yield f"data: Event {i} at {time.time()}\n\n"

421

time.sleep(1)

422

423

@app.get("/events")

424

def server_sent_events():

425

return StreamingResponse(

426

generate_server_sent_events(),

427

media_type="text/plain",

428

headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}

429

)

430

431

async def generate_async_stream() -> Iterator[bytes]:

432

"""Generate async streaming response."""

433

for chunk in range(100):

434

# Simulate async processing

435

await asyncio.sleep(0.01)

436

yield f"Chunk {chunk}\n".encode("utf-8")

437

438

@app.get("/stream/async")

439

async def async_stream():

440

return StreamingResponse(

441

generate_async_stream(),

442

media_type="text/plain"

443

)

444

```

445

446

### Response Headers and Background Tasks

447

448

```python

449

from fastapi import FastAPI, BackgroundTasks

450

from fastapi.responses import JSONResponse, FileResponse

451

import logging

452

453

app = FastAPI()

454

455

def log_download(filename: str, user_ip: str):

456

"""Background task to log file downloads."""

457

logging.info(f"File {filename} downloaded by {user_ip}")

458

459

@app.get("/secure-download/{filename}")

460

def secure_download(filename: str, background_tasks: BackgroundTasks, request: Request):

461

file_path = f"secure_files/{filename}"

462

463

# Add logging as background task

464

background_tasks.add_task(log_download, filename, request.client.host)

465

466

return FileResponse(

467

path=file_path,

468

filename=filename,

469

headers={

470

"X-Custom-Header": "Secure-Download",

471

"Cache-Control": "no-cache"

472

}

473

)

474

475

@app.get("/api/data-with-headers")

476

def data_with_custom_headers():

477

return JSONResponse(

478

content={"data": "response"},

479

headers={

480

"X-API-Version": "1.0",

481

"X-Response-Time": str(time.time()),

482

"Access-Control-Allow-Origin": "*"

483

}

484

)

485

```

486

487

## Types

488

489

```python { .api }

490

from typing import Any, Dict, Iterator, Optional, Union

491

from starlette.responses import Response

492

from starlette.background import BackgroundTask

493

494

# Response content types

495

ResponseContent = Union[str, bytes, Iterator[Any]]

496

497

# Headers type

498

ResponseHeaders = Optional[Dict[str, str]]

499

500

# Background task type

501

BackgroundTaskType = Optional[BackgroundTask]

502

503

# HTTP status codes for redirects

504

RedirectStatusCode = Union[301, 302, 303, 307, 308]

505

```