0
# Web Server
1
2
Full-featured asynchronous web server framework for building modern web applications and APIs. Supports applications, routing, middleware, static file serving, and comprehensive request/response handling with extensive customization options.
3
4
## Capabilities
5
6
### Application Management
7
8
The core application container that manages routes, middleware, and application lifecycle.
9
10
```python { .api }
11
class Application:
12
def __init__(
13
self,
14
*,
15
logger=None,
16
router=None,
17
middlewares=None,
18
handler_args=None,
19
client_max_size=1024**2,
20
debug=False,
21
**kwargs
22
):
23
"""
24
Create web application.
25
26
Parameters:
27
- logger: Application logger
28
- router: URL router instance
29
- middlewares: List of middleware functions
30
- handler_args: Arguments for request handlers
31
- client_max_size (int): Maximum client payload size
32
- debug (bool): Enable debug mode
33
"""
34
35
@property
36
def router(self):
37
"""Application URL router."""
38
39
def add_routes(self, routes):
40
"""Add multiple routes to application."""
41
42
def cleanup_ctx(self, coro):
43
"""Add cleanup context manager."""
44
45
def on_startup(self, coro):
46
"""Add startup hook."""
47
48
def on_shutdown(self, coro):
49
"""Add shutdown hook."""
50
51
def on_cleanup(self, coro):
52
"""Add cleanup hook."""
53
54
def __getitem__(self, key):
55
"""Get application data."""
56
57
def __setitem__(self, key, value):
58
"""Set application data."""
59
60
class AppKey:
61
def __init__(self, name, t):
62
"""
63
Type-safe application key.
64
65
Parameters:
66
- name (str): Key name
67
- t (type): Expected value type
68
"""
69
```
70
71
### Request and Response Handling
72
73
Objects representing HTTP requests and responses with comprehensive data access and manipulation methods.
74
75
```python { .api }
76
class Request:
77
@property
78
def method(self):
79
"""HTTP request method."""
80
81
@property
82
def url(self):
83
"""Request URL."""
84
85
@property
86
def path(self):
87
"""Request path."""
88
89
@property
90
def query(self):
91
"""Query parameters."""
92
93
@property
94
def headers(self):
95
"""Request headers."""
96
97
@property
98
def cookies(self):
99
"""Request cookies."""
100
101
@property
102
def content_type(self):
103
"""Request content type."""
104
105
@property
106
def content_length(self):
107
"""Request content length."""
108
109
async def read(self):
110
"""Read request body as bytes."""
111
112
async def text(self):
113
"""Read request body as text."""
114
115
async def json(self):
116
"""Parse request body as JSON."""
117
118
async def post(self):
119
"""Parse form data from request body."""
120
121
async def multipart(self):
122
"""Parse multipart data from request body."""
123
124
class BaseRequest:
125
"""Base class for HTTP requests."""
126
127
class Response:
128
def __init__(
129
self,
130
*,
131
body=None,
132
text=None,
133
status=200,
134
reason=None,
135
headers=None,
136
content_type=None,
137
charset=None,
138
**kwargs
139
):
140
"""
141
Create HTTP response.
142
143
Parameters:
144
- body (bytes): Response body as bytes
145
- text (str): Response body as text
146
- status (int): HTTP status code
147
- reason (str): HTTP reason phrase
148
- headers (dict): Response headers
149
- content_type (str): Content type
150
- charset (str): Text encoding
151
"""
152
153
@property
154
def status(self):
155
"""HTTP status code."""
156
157
@property
158
def headers(self):
159
"""Response headers."""
160
161
@property
162
def content_type(self):
163
"""Response content type."""
164
165
class StreamResponse:
166
def __init__(
167
self,
168
*,
169
status=200,
170
reason=None,
171
headers=None,
172
**kwargs
173
):
174
"""Streaming HTTP response."""
175
176
async def prepare(self, request):
177
"""Prepare response for streaming."""
178
179
async def write(self, data):
180
"""Write data to response stream."""
181
182
async def write_eof(self):
183
"""Signal end of response."""
184
185
def json_response(
186
data=None,
187
*,
188
text=None,
189
body=None,
190
status=200,
191
reason=None,
192
headers=None,
193
content_type='application/json',
194
dumps=None,
195
**kwargs
196
):
197
"""
198
Create JSON response.
199
200
Parameters:
201
- data: Object to serialize as JSON
202
- text (str): JSON text
203
- body (bytes): JSON body
204
- status (int): HTTP status code
205
- reason (str): HTTP reason phrase
206
- headers (dict): Response headers
207
- content_type (str): Content type
208
- dumps: JSON serialization function
209
210
Returns:
211
Response: JSON response object
212
"""
213
214
class FileResponse(StreamResponse):
215
def __init__(
216
self,
217
path,
218
*,
219
chunk_size=256*1024,
220
status=200,
221
reason=None,
222
headers=None,
223
**kwargs
224
):
225
"""
226
File-based HTTP response.
227
228
Parameters:
229
- path: File path
230
- chunk_size (int): Streaming chunk size
231
- status (int): HTTP status code
232
- reason (str): HTTP reason phrase
233
- headers (dict): Response headers
234
"""
235
```
236
237
### URL Routing and Dispatching
238
239
Comprehensive URL routing system with support for static routes, dynamic parameters, and resource-based organization.
240
241
```python { .api }
242
class UrlDispatcher:
243
def add_get(self, path, handler, **kwargs):
244
"""Add GET route."""
245
246
def add_post(self, path, handler, **kwargs):
247
"""Add POST route."""
248
249
def add_put(self, path, handler, **kwargs):
250
"""Add PUT route."""
251
252
def add_patch(self, path, handler, **kwargs):
253
"""Add PATCH route."""
254
255
def add_delete(self, path, handler, **kwargs):
256
"""Add DELETE route."""
257
258
def add_head(self, path, handler, **kwargs):
259
"""Add HEAD route."""
260
261
def add_options(self, path, handler, **kwargs):
262
"""Add OPTIONS route."""
263
264
def add_route(self, method, path, handler, **kwargs):
265
"""Add route for specific HTTP method."""
266
267
def add_static(self, prefix, path, **kwargs):
268
"""Add static file serving route."""
269
270
def add_resource(self, path, **kwargs):
271
"""Add URL resource."""
272
273
class AbstractResource:
274
"""Base class for URL resources."""
275
276
class Resource(AbstractResource):
277
"""URL resource with route collection."""
278
279
class DynamicResource(Resource):
280
"""Dynamic URL resource with path variables."""
281
282
class StaticResource(Resource):
283
"""Static file serving resource."""
284
285
class View:
286
"""Class-based view for handling requests."""
287
288
async def get(self):
289
"""Handle GET request."""
290
291
async def post(self):
292
"""Handle POST request."""
293
294
async def put(self):
295
"""Handle PUT request."""
296
297
async def patch(self):
298
"""Handle PATCH request."""
299
300
async def delete(self):
301
"""Handle DELETE request."""
302
```
303
304
### Route Definition Decorators
305
306
Decorator-based route definition system for clean and organized route registration.
307
308
```python { .api }
309
class RouteTableDef:
310
def __init__(self):
311
"""Collection of route definitions."""
312
313
def get(self, path, **kwargs):
314
"""GET route decorator."""
315
316
def post(self, path, **kwargs):
317
"""POST route decorator."""
318
319
def put(self, path, **kwargs):
320
"""PUT route decorator."""
321
322
def patch(self, path, **kwargs):
323
"""PATCH route decorator."""
324
325
def delete(self, path, **kwargs):
326
"""DELETE route decorator."""
327
328
def head(self, path, **kwargs):
329
"""HEAD route decorator."""
330
331
def options(self, path, **kwargs):
332
"""OPTIONS route decorator."""
333
334
def route(self, method, path, **kwargs):
335
"""Generic route decorator."""
336
337
def view(self, path, **kwargs):
338
"""Class-based view decorator."""
339
340
def static(self, prefix, path, **kwargs):
341
"""Static file route decorator."""
342
343
def get(path, **kwargs):
344
"""Standalone GET route decorator."""
345
346
def post(path, **kwargs):
347
"""Standalone POST route decorator."""
348
349
def put(path, **kwargs):
350
"""Standalone PUT route decorator."""
351
352
def patch(path, **kwargs):
353
"""Standalone PATCH route decorator."""
354
355
def delete(path, **kwargs):
356
"""Standalone DELETE route decorator."""
357
358
def head(path, **kwargs):
359
"""Standalone HEAD route decorator."""
360
361
def options(path, **kwargs):
362
"""Standalone OPTIONS route decorator."""
363
364
def route(method, path, **kwargs):
365
"""Standalone generic route decorator."""
366
367
def view(path, **kwargs):
368
"""Standalone class-based view decorator."""
369
370
def static(prefix, path, **kwargs):
371
"""Standalone static file route decorator."""
372
```
373
374
### Middleware System
375
376
Extensible middleware system for request/response processing, authentication, and cross-cutting concerns.
377
378
```python { .api }
379
def middleware(coro):
380
"""
381
Decorator for creating middleware functions.
382
383
Parameters:
384
- coro: Async function that processes requests
385
386
Returns:
387
Middleware function
388
"""
389
390
def normalize_path_middleware(
391
*,
392
append_slash=True,
393
remove_slash=False,
394
merge_slashes=True,
395
redirect_class=None
396
):
397
"""
398
Path normalization middleware.
399
400
Parameters:
401
- append_slash (bool): Append trailing slash
402
- remove_slash (bool): Remove trailing slash
403
- merge_slashes (bool): Merge consecutive slashes
404
- redirect_class: HTTP redirect class
405
406
Returns:
407
Middleware function
408
"""
409
```
410
411
### Application Runner and Sites
412
413
Application lifecycle management and server binding for different transport types.
414
415
```python { .api }
416
class AppRunner:
417
def __init__(self, app, **kwargs):
418
"""
419
Application runner.
420
421
Parameters:
422
- app: Web application instance
423
"""
424
425
async def setup(self):
426
"""Setup application runner."""
427
428
async def cleanup(self):
429
"""Cleanup application runner."""
430
431
class BaseRunner:
432
"""Base class for application runners."""
433
434
class ServerRunner(BaseRunner):
435
def __init__(self, web_server, **kwargs):
436
"""Runner for raw request handlers."""
437
438
class BaseSite:
439
"""Base class for server sites."""
440
441
class TCPSite(BaseSite):
442
def __init__(
443
self,
444
runner,
445
host=None,
446
port=None,
447
*,
448
ssl_context=None,
449
backlog=128,
450
reuse_address=None,
451
reuse_port=None,
452
**kwargs
453
):
454
"""
455
TCP server site.
456
457
Parameters:
458
- runner: Application runner
459
- host (str): Bind host
460
- port (int): Bind port
461
- ssl_context: SSL context
462
- backlog (int): Socket backlog
463
- reuse_address (bool): Reuse address
464
- reuse_port (bool): Reuse port
465
"""
466
467
async def start(self):
468
"""Start server site."""
469
470
async def stop(self):
471
"""Stop server site."""
472
473
class UnixSite(BaseSite):
474
def __init__(self, runner, path, **kwargs):
475
"""Unix domain socket site."""
476
477
class NamedPipeSite(BaseSite):
478
def __init__(self, runner, path, **kwargs):
479
"""Named pipe site (Windows)."""
480
481
def run_app(
482
app,
483
*,
484
host=None,
485
port=None,
486
path=None,
487
sock=None,
488
shutdown_timeout=60.0,
489
keepalive_timeout=75.0,
490
ssl_context=None,
491
print=print,
492
backlog=128,
493
access_log_class=None,
494
access_log_format=None,
495
access_log=None,
496
handle_signals=True,
497
reuse_address=None,
498
reuse_port=None,
499
handler_cancellation=False,
500
loop=None
501
):
502
"""
503
Run web application.
504
505
Parameters:
506
- app: Web application or coroutine returning application
507
- host (str or list): Server host(s)
508
- port (int): Server port
509
- path (str or list): Unix socket path(s)
510
- sock: Raw socket or list of sockets
511
- shutdown_timeout (float): Shutdown timeout
512
- keepalive_timeout (float): Keep-alive timeout
513
- ssl_context: SSL context
514
- print: Print function for startup messages
515
- backlog (int): Socket backlog
516
- access_log_class: Access log class
517
- access_log_format (str): Access log format
518
- access_log: Access logger instance
519
- handle_signals (bool): Handle OS signals
520
- reuse_address (bool): Reuse address option
521
- reuse_port (bool): Reuse port option
522
- handler_cancellation (bool): Enable handler cancellation
523
- loop: Event loop
524
"""
525
```
526
527
### HTTP Status Code Exceptions
528
529
Comprehensive HTTP status code exception classes for proper HTTP response handling.
530
531
```python { .api }
532
class HTTPException(Exception):
533
"""Base HTTP exception."""
534
535
@property
536
def status_code(self):
537
"""HTTP status code."""
538
539
# Success responses (2xx)
540
class HTTPOk(HTTPException):
541
"""200 OK response."""
542
543
class HTTPCreated(HTTPException):
544
"""201 Created response."""
545
546
class HTTPNoContent(HTTPException):
547
"""204 No Content response."""
548
549
# Redirection responses (3xx)
550
class HTTPMovedPermanently(HTTPException):
551
"""301 Moved Permanently response."""
552
553
class HTTPFound(HTTPException):
554
"""302 Found response."""
555
556
class HTTPNotModified(HTTPException):
557
"""304 Not Modified response."""
558
559
# Client error responses (4xx)
560
class HTTPBadRequest(HTTPException):
561
"""400 Bad Request response."""
562
563
class HTTPUnauthorized(HTTPException):
564
"""401 Unauthorized response."""
565
566
class HTTPForbidden(HTTPException):
567
"""403 Forbidden response."""
568
569
class HTTPNotFound(HTTPException):
570
"""404 Not Found response."""
571
572
class HTTPMethodNotAllowed(HTTPException):
573
"""405 Method Not Allowed response."""
574
575
class HTTPConflict(HTTPException):
576
"""409 Conflict response."""
577
578
# Server error responses (5xx)
579
class HTTPInternalServerError(HTTPException):
580
"""500 Internal Server Error response."""
581
582
class HTTPNotImplemented(HTTPException):
583
"""501 Not Implemented response."""
584
585
class HTTPBadGateway(HTTPException):
586
"""502 Bad Gateway response."""
587
588
class HTTPServiceUnavailable(HTTPException):
589
"""503 Service Unavailable response."""
590
```
591
592
## Usage Examples
593
594
### Basic Web Application
595
596
```python
597
from aiohttp import web
598
599
async def hello_handler(request):
600
name = request.match_info.get('name', 'World')
601
return web.Response(text=f"Hello, {name}!")
602
603
async def json_handler(request):
604
data = {'message': 'Hello, JSON!', 'status': 'success'}
605
return web.json_response(data)
606
607
# Create application
608
app = web.Application()
609
610
# Add routes
611
app.router.add_get('/', hello_handler)
612
app.router.add_get('/hello/{name}', hello_handler)
613
app.router.add_get('/json', json_handler)
614
615
# Run application
616
if __name__ == '__main__':
617
web.run_app(app, host='localhost', port=8080)
618
```
619
620
### Route Table Definitions
621
622
```python
623
from aiohttp import web
624
625
routes = web.RouteTableDef()
626
627
@routes.get('/')
628
async def index(request):
629
return web.Response(text="Welcome to the API")
630
631
@routes.get('/users/{user_id}')
632
async def get_user(request):
633
user_id = request.match_info['user_id']
634
return web.json_response({'user_id': user_id})
635
636
@routes.post('/users')
637
async def create_user(request):
638
data = await request.json()
639
# Process user creation
640
return web.json_response({'created': True}, status=201)
641
642
# Create application and add routes
643
app = web.Application()
644
app.add_routes(routes)
645
646
web.run_app(app, port=8080)
647
```
648
649
### Middleware Usage
650
651
```python
652
from aiohttp import web
653
import time
654
655
@web.middleware
656
async def timing_middleware(request, handler):
657
start_time = time.time()
658
response = await handler(request)
659
process_time = time.time() - start_time
660
response.headers['X-Process-Time'] = str(process_time)
661
return response
662
663
@web.middleware
664
async def auth_middleware(request, handler):
665
auth_header = request.headers.get('Authorization')
666
if not auth_header:
667
raise web.HTTPUnauthorized()
668
669
# Validate authentication
670
return await handler(request)
671
672
# Create application with middleware
673
app = web.Application(middlewares=[timing_middleware, auth_middleware])
674
675
async def protected_handler(request):
676
return web.json_response({'message': 'Access granted'})
677
678
app.router.add_get('/protected', protected_handler)
679
680
web.run_app(app)
681
```
682
683
### Class-Based Views
684
685
```python
686
from aiohttp import web
687
688
class UserView(web.View):
689
async def get(self):
690
user_id = self.request.match_info['user_id']
691
# Fetch user data
692
return web.json_response({'user_id': user_id})
693
694
async def post(self):
695
data = await self.request.json()
696
# Create user
697
return web.json_response({'created': True}, status=201)
698
699
async def put(self):
700
user_id = self.request.match_info['user_id']
701
data = await self.request.json()
702
# Update user
703
return web.json_response({'updated': True})
704
705
async def delete(self):
706
user_id = self.request.match_info['user_id']
707
# Delete user
708
return web.Response(status=204)
709
710
# Add class-based view to router
711
app = web.Application()
712
app.router.add_view('/users/{user_id}', UserView)
713
714
web.run_app(app)
715
```