or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-routing.mdconfiguration.mddto.mdexceptions.mdhttp-handlers.mdindex.mdmiddleware.mdopenapi.mdplugins.mdrequest-response.mdsecurity.mdtesting.mdwebsocket.md

http-handlers.mddocs/

0

# HTTP Route Handlers

1

2

Decorators and classes for handling HTTP requests including GET, POST, PUT, DELETE, PATCH, and generic route handlers. Route handlers process incoming HTTP requests and generate responses.

3

4

## Capabilities

5

6

### HTTP Method Decorators

7

8

Decorators for creating route handlers for specific HTTP methods. Each decorator creates an HTTPRouteHandler instance configured for the specified HTTP method.

9

10

```python { .api }

11

def get(

12

path: str | Sequence[str] | None = None,

13

*,

14

after_request: AfterRequestHookHandler | None = None,

15

after_response: AfterResponseHookHandler | None = None,

16

background: BackgroundTask | BackgroundTasks | None = None,

17

before_request: BeforeRequestHookHandler | None = None,

18

cache: bool | int | CacheKeyBuilder = False,

19

dependencies: Dependencies | None = None,

20

dto: type[AbstractDTO] | None = None,

21

etag: ETagConfig | None = None,

22

exception_handlers: ExceptionHandlersMap | None = None,

23

guards: Sequence[Guard] | None = None,

24

http_method: HttpMethod | str = HttpMethod.GET,

25

media_type: MediaType | str | None = None,

26

middleware: Sequence[Middleware] | None = None,

27

name: str | None = None,

28

opt: dict[str, Any] | None = None,

29

return_dto: type[AbstractDTO] | None = None,

30

signature_namespace: dict[str, Any] | None = None,

31

status_code: int | None = None,

32

summary: str | None = None,

33

description: str | None = None,

34

tags: Sequence[str] | None = None,

35

type_encoders: TypeEncodersMap | None = None,

36

include_in_schema: bool = True,

37

sync_to_thread: bool = True,

38

content_encoding: str | None = None,

39

content_media_type: str | None = None,

40

) -> Callable[[AnyCallable], HTTPRouteHandler]:

41

"""

42

Create a route handler for GET requests.

43

44

Parameters:

45

- path: Route path(s) - can be a string or sequence of strings

46

- after_request: Hook called after request processing

47

- after_response: Hook called after response sending

48

- background: Background task(s) to execute after response

49

- before_request: Hook called before request processing

50

- cache: Response caching configuration

51

- dependencies: Route-specific dependency providers

52

- dto: DTO for request body serialization

53

- etag: ETag configuration for caching

54

- exception_handlers: Route-specific exception handlers

55

- guards: Authorization guards

56

- http_method: HTTP method (defaults to GET)

57

- media_type: Response media type

58

- middleware: Route-specific middleware

59

- name: Route name for URL generation

60

- opt: Arbitrary options dictionary

61

- return_dto: DTO for response serialization

62

- signature_namespace: Additional namespace for signature inspection

63

- status_code: Default response status code

64

- summary: OpenAPI summary

65

- description: OpenAPI description

66

- tags: OpenAPI tags

67

- type_encoders: Route-specific type encoders

68

- include_in_schema: Include in OpenAPI schema

69

- sync_to_thread: Run sync handlers in thread pool

70

- content_encoding: Response content encoding

71

- content_media_type: Response content media type

72

73

Returns:

74

Decorator function that creates an HTTPRouteHandler

75

"""

76

77

def post(

78

path: str | Sequence[str] | None = None,

79

**kwargs: Any

80

) -> Callable[[AnyCallable], HTTPRouteHandler]:

81

"""Create a route handler for POST requests."""

82

83

def put(

84

path: str | Sequence[str] | None = None,

85

**kwargs: Any

86

) -> Callable[[AnyCallable], HTTPRouteHandler]:

87

"""Create a route handler for PUT requests."""

88

89

def patch(

90

path: str | Sequence[str] | None = None,

91

**kwargs: Any

92

) -> Callable[[AnyCallable], HTTPRouteHandler]:

93

"""Create a route handler for PATCH requests."""

94

95

def delete(

96

path: str | Sequence[str] | None = None,

97

**kwargs: Any

98

) -> Callable[[AnyCallable], HTTPRouteHandler]:

99

"""Create a route handler for DELETE requests."""

100

101

def head(

102

path: str | Sequence[str] | None = None,

103

**kwargs: Any

104

) -> Callable[[AnyCallable], HTTPRouteHandler]:

105

"""Create a route handler for HEAD requests."""

106

107

def route(

108

path: str | Sequence[str] | None = None,

109

*,

110

http_method: HttpMethod | str | Sequence[HttpMethod | str],

111

**kwargs: Any

112

) -> Callable[[AnyCallable], HTTPRouteHandler]:

113

"""Create a route handler for multiple HTTP methods."""

114

```

115

116

### HTTPRouteHandler Class

117

118

The underlying route handler class created by HTTP method decorators. Can be instantiated directly for advanced configuration.

119

120

```python { .api }

121

class HTTPRouteHandler(BaseRouteHandler):

122

def __init__(

123

self,

124

fn: AnyCallable,

125

*,

126

http_method: HttpMethod | str | Sequence[HttpMethod | str],

127

path: str | Sequence[str] | None = None,

128

status_code: int | None = None,

129

media_type: MediaType | str | None = None,

130

# ... same parameters as decorators

131

):

132

"""

133

Create an HTTP route handler.

134

135

Parameters:

136

- fn: Handler function

137

- http_method: HTTP method(s) to handle

138

- path: Route path(s)

139

- status_code: Default response status code

140

- media_type: Response media type

141

"""

142

143

@property

144

def http_methods(self) -> set[Method]:

145

"""Get HTTP methods handled by this route."""

146

147

async def handle_request(self, request: Request) -> Response:

148

"""Process incoming request and generate response."""

149

```

150

151

### ASGI Route Handler

152

153

Route handler for integrating existing ASGI applications or middleware.

154

155

```python { .api }

156

def asgi(

157

path: str | Sequence[str] | None = None,

158

*,

159

is_mount: bool = False,

160

**kwargs: Any

161

) -> Callable[[Callable[[Scope, Receive, Send], Awaitable[None]]], ASGIRouteHandler]:

162

"""

163

Create an ASGI route handler.

164

165

Parameters:

166

- path: Route path(s)

167

- is_mount: Whether to mount the ASGI app at the path

168

"""

169

170

class ASGIRouteHandler(BaseRouteHandler):

171

def __init__(

172

self,

173

fn: Callable[[Scope, Receive, Send], Awaitable[None]],

174

*,

175

is_mount: bool = False,

176

**kwargs: Any

177

):

178

"""Create an ASGI route handler."""

179

```

180

181

### Path Parameters

182

183

Path parameter parsing with type conversion and validation.

184

185

```python { .api }

186

# Path parameter types in route paths:

187

# {param_name:int} - Integer parameter

188

# {param_name:float} - Float parameter

189

# {param_name:str} - String parameter (default)

190

# {param_name:uuid} - UUID parameter

191

# {param_name:path} - Path parameter (preserves slashes)

192

```

193

194

## Usage Examples

195

196

### Basic Route Handlers

197

198

```python

199

from litestar import get, post, put, delete

200

from litestar.dto import DataclassDTO

201

from dataclasses import dataclass

202

203

@dataclass

204

class User:

205

name: str

206

email: str

207

id: int | None = None

208

209

@get("/users")

210

async def list_users() -> list[User]:

211

return [User(id=1, name="Alice", email="alice@example.com")]

212

213

@get("/users/{user_id:int}")

214

async def get_user(user_id: int) -> User:

215

return User(id=user_id, name="Alice", email="alice@example.com")

216

217

@post("/users", dto=DataclassDTO[User])

218

async def create_user(data: User) -> User:

219

# Simulate user creation

220

data.id = 123

221

return data

222

223

@put("/users/{user_id:int}", dto=DataclassDTO[User])

224

async def update_user(user_id: int, data: User) -> User:

225

data.id = user_id

226

return data

227

228

@delete("/users/{user_id:int}")

229

async def delete_user(user_id: int) -> dict[str, str]:

230

return {"status": "deleted", "user_id": str(user_id)}

231

```

232

233

### Path Parameters and Query Parameters

234

235

```python

236

from litestar import get

237

from litestar.params import Parameter

238

239

@get("/users/{user_id:int}/posts/{post_id:uuid}")

240

async def get_user_post(

241

user_id: int,

242

post_id: UUID,

243

include_comments: bool = False,

244

limit: int = Parameter(default=10, ge=1, le=100)

245

) -> dict:

246

return {

247

"user_id": user_id,

248

"post_id": str(post_id),

249

"include_comments": include_comments,

250

"limit": limit

251

}

252

```

253

254

### Request Body Handling

255

256

```python

257

from litestar import post

258

from litestar.dto import DataclassDTO

259

from dataclasses import dataclass

260

from typing import Optional

261

262

@dataclass

263

class CreateUserRequest:

264

name: str

265

email: str

266

age: Optional[int] = None

267

268

@post("/users", dto=DataclassDTO[CreateUserRequest])

269

async def create_user_with_validation(data: CreateUserRequest) -> dict:

270

# data is automatically validated and converted

271

return {"message": f"Created user {data.name} with email {data.email}"}

272

273

# For raw request body access

274

@post("/upload")

275

async def upload_file(request: Request) -> dict:

276

body = await request.body()

277

return {"size": len(body)}

278

```

279

280

### Multiple HTTP Methods

281

282

```python

283

from litestar import route, HttpMethod

284

285

@route("/api/resource", http_method=[HttpMethod.GET, HttpMethod.POST])

286

async def handle_resource(request: Request) -> dict:

287

if request.method == "GET":

288

return {"action": "fetch"}

289

elif request.method == "POST":

290

data = await request.json()

291

return {"action": "create", "data": data}

292

```

293

294

### Response Configuration

295

296

```python

297

from litestar import get, post

298

from litestar.response import Response

299

from litestar.status_codes import HTTP_201_CREATED, HTTP_202_ACCEPTED

300

301

@get("/health", status_code=200, media_type="text/plain")

302

async def health_check() -> str:

303

return "OK"

304

305

@post("/async-task", status_code=HTTP_202_ACCEPTED)

306

async def start_async_task(data: dict) -> dict:

307

# Start background processing

308

return {"task_id": "12345", "status": "accepted"}

309

310

@post("/users", status_code=HTTP_201_CREATED)

311

async def create_user_with_status(data: dict) -> dict:

312

# User creation logic

313

return {"id": 123, "status": "created"}

314

```

315

316

### Custom Response Types

317

318

```python

319

from litestar import get

320

from litestar.response import File, Stream, Redirect, Template

321

322

@get("/download/{filename:str}")

323

async def download_file(filename: str) -> File:

324

return File(f"/uploads/{filename}")

325

326

@get("/stream")

327

async def stream_data() -> Stream:

328

async def generate():

329

for i in range(100):

330

yield f"data chunk {i}\n"

331

332

return Stream(generate())

333

334

@get("/redirect")

335

async def redirect_example() -> Redirect:

336

return Redirect("/new-location")

337

338

@get("/page")

339

async def render_page() -> Template:

340

return Template("page.html", context={"title": "My Page"})

341

```

342

343

### Error Handling in Routes

344

345

```python

346

from litestar import get

347

from litestar.exceptions import HTTPException, NotFoundException

348

from litestar.status_codes import HTTP_400_BAD_REQUEST

349

350

@get("/users/{user_id:int}")

351

async def get_user_safe(user_id: int) -> dict:

352

if user_id < 1:

353

raise HTTPException(

354

detail="User ID must be positive",

355

status_code=HTTP_400_BAD_REQUEST

356

)

357

358

# Simulate user lookup

359

if user_id == 999:

360

raise NotFoundException("User not found")

361

362

return {"id": user_id, "name": "Alice"}

363

```

364

365

### Background Tasks

366

367

```python

368

from litestar import post

369

from litestar.background_tasks import BackgroundTask

370

371

def send_email(email: str, message: str) -> None:

372

# Email sending logic

373

print(f"Sending email to {email}: {message}")

374

375

@post("/notify", background=BackgroundTask(send_email, "admin@example.com", "New user registered"))

376

async def notify_admin(user_data: dict) -> dict:

377

return {"status": "success", "message": "Notification queued"}

378

```

379

380

## Types

381

382

```python { .api }

383

# Route handler function types

384

AnyCallable = Callable[..., Any]

385

RouteHandlerFunction = Callable[..., Any | Awaitable[Any]]

386

387

# HTTP method types

388

Method = Literal["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "TRACE"]

389

390

# Hook handler types

391

AfterRequestHookHandler = Callable[[Request], None | Awaitable[None]]

392

AfterResponseHookHandler = Callable[[Request, Response], None | Awaitable[None]]

393

BeforeRequestHookHandler = Callable[[Request], None | Awaitable[None]]

394

395

# Guard type

396

Guard = Callable[[ASGIConnection, BaseRouteHandler], bool | Awaitable[bool]]

397

398

# Cache types

399

CacheKeyBuilder = Callable[[Request], str]

400

401

# Type encoders

402

TypeEncodersMap = dict[Any, Callable[[Any], Any]]

403

```