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
```