or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context.mdcore-application.mdhelpers.mdindex.mdrequest-response.mdsignals.mdtemplates.mdtesting.mdwebsocket.md

request-response.mddocs/

0

# Request and Response System

1

2

Async HTTP request/response handling with comprehensive data access, form processing, file uploads, JSON support, and flexible response creation.

3

4

## Capabilities

5

6

### HTTP Request Handling

7

8

Represents HTTP requests with async support for body data, form processing, and file uploads.

9

10

```python { .api }

11

class Request:

12

# Core request attributes

13

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

14

path: str # URL path

15

query_string: bytes # Raw query string

16

args: ImmutableMultiDict # Parsed query string arguments

17

headers: Headers # Request headers

18

cookies: ImmutableDict # Request cookies

19

endpoint: str | None # Matched endpoint name

20

view_args: dict | None # URL rule arguments

21

blueprint: str | None # Current blueprint name

22

23

# Async data access methods

24

async def get_json(

25

self,

26

force: bool = False,

27

silent: bool = False,

28

cache: bool = True

29

):

30

"""

31

Get JSON data from request body.

32

33

Args:

34

force: Parse even if content type isn't JSON

35

silent: Return None instead of raising on error

36

cache: Cache the parsed result

37

38

Returns:

39

Parsed JSON data or None

40

"""

41

42

async def get_data(self, cache: bool = True, as_text: bool = False):

43

"""

44

Get raw request body data.

45

46

Args:

47

cache: Cache the data for subsequent calls

48

as_text: Return as text instead of bytes

49

50

Returns:

51

Request body as bytes or str

52

"""

53

54

# Async properties (use await)

55

@property

56

async def form(self) -> ImmutableMultiDict:

57

"""Form data from request body."""

58

59

@property

60

async def files(self) -> ImmutableMultiDict:

61

"""Uploaded files from request body."""

62

63

@property

64

async def json(self):

65

"""JSON data from request body."""

66

67

@property

68

async def body(self):

69

"""Raw request body as async iterable."""

70

```

71

72

### HTTP Response Creation

73

74

Flexible response objects with header management, cookie support, and conditional response features.

75

76

```python { .api }

77

class Response:

78

# Core response attributes

79

status_code: int # HTTP status code

80

headers: Headers # Response headers

81

data: bytes # Response body data

82

mimetype: str | None # MIME type

83

content_type: str | None # Content-Type header

84

85

def set_cookie(

86

self,

87

key: str,

88

value: str = "",

89

max_age: int | None = None,

90

expires: datetime | None = None,

91

path: str | None = None,

92

domain: str | None = None,

93

secure: bool = False,

94

httponly: bool = False,

95

samesite: str | None = None

96

):

97

"""

98

Set response cookie.

99

100

Args:

101

key: Cookie name

102

value: Cookie value

103

max_age: Cookie lifetime in seconds

104

expires: Cookie expiration datetime

105

path: Cookie path

106

domain: Cookie domain

107

secure: HTTPS only flag

108

httponly: HTTP only flag (no JavaScript access)

109

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

110

"""

111

112

def delete_cookie(

113

self,

114

key: str,

115

path: str = "/",

116

domain: str | None = None

117

):

118

"""

119

Delete cookie by setting empty value and past expiration.

120

121

Args:

122

key: Cookie name to delete

123

path: Cookie path

124

domain: Cookie domain

125

"""

126

127

async def make_conditional(

128

self,

129

request: Request,

130

accept_ranges: bool = False,

131

complete_length: int | None = None

132

):

133

"""

134

Make response conditional based on request headers.

135

136

Args:

137

request: The request object

138

accept_ranges: Whether to accept range requests

139

complete_length: Complete content length for range requests

140

"""

141

```

142

143

### File Upload Support

144

145

Uploaded file wrapper with async file operations and metadata access.

146

147

```python { .api }

148

class FileStorage:

149

# File metadata

150

filename: str | None # Original filename

151

name: str | None # Form field name

152

content_type: str | None # MIME content type

153

content_length: int | None # Content length

154

headers: Headers # File headers

155

156

async def save(self, dst: str, buffer_size: int = 16384):

157

"""

158

Save file to disk asynchronously.

159

160

Args:

161

dst: Destination file path

162

buffer_size: Buffer size for file operations

163

"""

164

165

async def read(self, size: int = -1) -> bytes:

166

"""

167

Read file data.

168

169

Args:

170

size: Number of bytes to read (-1 for all)

171

172

Returns:

173

File data as bytes

174

"""

175

176

async def readline(self, size: int = -1) -> bytes:

177

"""

178

Read line from file.

179

180

Args:

181

size: Maximum line length (-1 for unlimited)

182

183

Returns:

184

Line data as bytes

185

"""

186

187

async def readlines(self, hint: int = -1) -> list[bytes]:

188

"""

189

Read lines from file.

190

191

Args:

192

hint: Approximate number of bytes to read

193

194

Returns:

195

List of lines as bytes

196

"""

197

```

198

199

### Usage Examples

200

201

#### Request Data Access

202

203

```python

204

from quart import Quart, request, jsonify

205

206

app = Quart(__name__)

207

208

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

209

async def handle_form():

210

# Access form data

211

form_data = await request.form

212

username = form_data.get('username')

213

214

# Access JSON data

215

json_data = await request.get_json()

216

217

# Access query parameters

218

search = request.args.get('search', '')

219

220

# Access headers

221

auth_header = request.headers.get('Authorization')

222

223

return jsonify({

224

'username': username,

225

'json': json_data,

226

'search': search,

227

'auth': auth_header

228

})

229

230

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

231

async def handle_upload():

232

# Access uploaded files

233

files = await request.files

234

uploaded_file = files.get('document')

235

236

if uploaded_file and uploaded_file.filename:

237

# Save file

238

await uploaded_file.save(f'/uploads/{uploaded_file.filename}')

239

240

# Read file content

241

content = await uploaded_file.read()

242

243

return f'Uploaded {uploaded_file.filename} ({len(content)} bytes)'

244

245

return 'No file uploaded'

246

```

247

248

#### Response Creation

249

250

```python

251

from quart import Quart, make_response, jsonify

252

253

app = Quart(__name__)

254

255

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

256

async def custom_response():

257

# Create custom response

258

response = await make_response('Custom content')

259

response.status_code = 201

260

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

261

262

# Set cookie

263

response.set_cookie('session_id', 'abc123', max_age=3600, httponly=True)

264

265

return response

266

267

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

268

async def json_response():

269

# JSON response with custom headers

270

response = jsonify({'status': 'success', 'data': [1, 2, 3]})

271

response.headers['Cache-Control'] = 'no-cache'

272

return response

273

274

@app.route('/conditional')

275

async def conditional_response():

276

# Create conditional response

277

response = await make_response('Content that might be cached')

278

await response.make_conditional(request)

279

return response

280

```

281

282

#### Request Context Usage

283

284

```python

285

from quart import Quart, request, g

286

287

app = Quart(__name__)

288

289

@app.before_request

290

async def before_request():

291

# Access request data in before_request

292

g.start_time = time.time()

293

g.user_agent = request.headers.get('User-Agent')

294

295

# Parse JSON for all POST requests

296

if request.method == 'POST':

297

g.json_data = await request.get_json(silent=True)

298

299

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

300

async def process_data():

301

# Use pre-parsed data from g

302

data = getattr(g, 'json_data', {})

303

304

return jsonify({

305

'processed': data,

306

'user_agent': g.user_agent,

307

'processing_time': time.time() - g.start_time

308

})

309

```