0
# Async Integration
1
2
Programmatic interfaces for integrating Hypercorn with asyncio and trio async frameworks. These functions provide fine-grained control over server lifecycle, allowing embedding Hypercorn servers within larger async applications.
3
4
## Capabilities
5
6
### Asyncio Integration
7
8
Serve ASGI and WSGI applications using the asyncio event loop with optional shutdown triggers and mode specification.
9
10
```python { .api }
11
async def serve(
12
app: ASGIFramework | WSGIFramework,
13
config: Config,
14
*,
15
shutdown_trigger: Callable[..., Awaitable[None]] | None = None,
16
mode: str | None = None
17
) -> None:
18
"""
19
Programmatic interface for serving applications with asyncio.
20
21
Starts a Hypercorn server within an asyncio event loop, providing
22
full control over server lifecycle and shutdown handling. Ideal for
23
embedding Hypercorn within larger asyncio applications or for
24
custom server management.
25
26
Args:
27
app: ASGI or WSGI application to serve
28
config: Config object with server settings
29
shutdown_trigger: Optional async callable that when awaited
30
triggers graceful server shutdown
31
mode: Optional mode specification ("asgi" or "wsgi").
32
If not provided, mode is auto-detected
33
34
Returns:
35
None - function completes when server shuts down
36
37
Example shutdown triggers:
38
- asyncio.Event.wait()
39
- signal handling coroutines
40
- custom application shutdown logic
41
"""
42
```
43
44
### Trio Integration
45
46
Serve ASGI and WSGI applications using the trio async framework with task status reporting and shutdown triggers.
47
48
```python { .api }
49
async def serve(
50
app: ASGIFramework | WSGIFramework,
51
config: Config,
52
*,
53
shutdown_trigger: Callable[..., Awaitable[None]] | None = None,
54
task_status: trio._core._run._TaskStatus = trio.TASK_STATUS_IGNORED,
55
mode: str | None = None
56
) -> None:
57
"""
58
Programmatic interface for serving applications with trio.
59
60
Starts a Hypercorn server within a trio nursery, with support for
61
trio's structured concurrency patterns and task status reporting.
62
63
Args:
64
app: ASGI or WSGI application to serve
65
config: Config object with server settings
66
shutdown_trigger: Optional async callable that when awaited
67
triggers graceful server shutdown
68
task_status: Trio task status object for nursery integration
69
mode: Optional mode specification ("asgi" or "wsgi").
70
If not provided, mode is auto-detected
71
72
Returns:
73
None - function completes when server shuts down
74
75
Task status is used with trio nurseries to indicate when
76
the server has started and is ready to accept connections.
77
"""
78
```
79
80
## Framework Types
81
82
Type definitions for supported application frameworks.
83
84
```python { .api }
85
# ASGI application type
86
ASGIFramework = Callable[[Scope, ASGIReceiveCallable, ASGISendCallable], Awaitable[None]]
87
88
# WSGI application type
89
WSGIFramework = Callable[[dict, Callable], Iterable[bytes]]
90
91
# Union type for framework detection
92
Framework = ASGIFramework | WSGIFramework
93
```
94
95
## Usage Examples
96
97
### Basic Asyncio Integration
98
99
```python
100
import asyncio
101
from hypercorn.config import Config
102
from hypercorn.asyncio import serve
103
104
async def app(scope, receive, send):
105
"""Simple ASGI application"""
106
await send({
107
'type': 'http.response.start',
108
'status': 200,
109
'headers': [[b'content-type', b'text/plain']],
110
})
111
await send({
112
'type': 'http.response.body',
113
'body': b'Hello World',
114
})
115
116
async def main():
117
config = Config()
118
config.bind = ["127.0.0.1:8000"]
119
120
# Serve until manually stopped
121
await serve(app, config)
122
123
asyncio.run(main())
124
```
125
126
### Asyncio with Shutdown Trigger
127
128
```python
129
import asyncio
130
import signal
131
from hypercorn.config import Config
132
from hypercorn.asyncio import serve
133
134
async def shutdown_trigger():
135
"""Wait for SIGTERM or SIGINT"""
136
shutdown_event = asyncio.Event()
137
138
def signal_handler():
139
shutdown_event.set()
140
141
loop = asyncio.get_event_loop()
142
loop.add_signal_handler(signal.SIGTERM, signal_handler)
143
loop.add_signal_handler(signal.SIGINT, signal_handler)
144
145
await shutdown_event.wait()
146
147
async def main():
148
config = Config()
149
config.bind = ["0.0.0.0:8000"]
150
151
# Serve with graceful shutdown on signals
152
await serve(app, config, shutdown_trigger=shutdown_trigger)
153
154
asyncio.run(main())
155
```
156
157
### Trio Integration
158
159
```python
160
import trio
161
from hypercorn.config import Config
162
from hypercorn.trio import serve
163
164
async def app(scope, receive, send):
165
"""Simple ASGI application"""
166
await send({
167
'type': 'http.response.start',
168
'status': 200,
169
'headers': [[b'content-type', b'text/plain']],
170
})
171
await send({
172
'type': 'http.response.body',
173
'body': b'Hello World',
174
})
175
176
async def main():
177
config = Config()
178
config.bind = ["127.0.0.1:8000"]
179
180
async with trio.open_nursery() as nursery:
181
# Start server in nursery
182
nursery.start_soon(serve, app, config, task_status=trio.TASK_STATUS_IGNORED)
183
184
# Server is now running - do other work
185
await trio.sleep(60) # Run for 60 seconds
186
187
# Nursery cleanup will shutdown server
188
189
trio.run(main)
190
```
191
192
### Custom Shutdown Logic
193
194
```python
195
import asyncio
196
from hypercorn.config import Config
197
from hypercorn.asyncio import serve
198
199
class ServerManager:
200
def __init__(self):
201
self.shutdown_event = asyncio.Event()
202
203
async def start_server(self, app):
204
config = Config()
205
config.bind = ["0.0.0.0:8000"]
206
207
# Serve with custom shutdown trigger
208
await serve(app, config, shutdown_trigger=self.shutdown_event.wait)
209
210
def shutdown(self):
211
"""Trigger graceful shutdown"""
212
self.shutdown_event.set()
213
214
# Usage
215
manager = ServerManager()
216
217
# In one task
218
asyncio.create_task(manager.start_server(app))
219
220
# Later, from another part of application
221
manager.shutdown() # Triggers graceful shutdown
222
```
223
224
### WSGI Application Integration
225
226
```python
227
import asyncio
228
from hypercorn.config import Config
229
from hypercorn.asyncio import serve
230
231
def wsgi_app(environ, start_response):
232
"""Simple WSGI application"""
233
status = '200 OK'
234
headers = [('Content-type', 'text/plain')]
235
start_response(status, headers)
236
return [b'Hello World']
237
238
async def main():
239
config = Config()
240
config.bind = ["127.0.0.1:8000"]
241
242
# Serve WSGI app (mode auto-detected)
243
await serve(wsgi_app, config)
244
245
asyncio.run(main())
246
```
247
248
### Mixed ASGI/WSGI Mode
249
250
```python
251
async def main():
252
config = Config()
253
config.bind = ["127.0.0.1:8000"]
254
255
# Explicitly specify mode (useful for ambiguous applications)
256
await serve(app, config, mode="asgi")
257
# or
258
await serve(wsgi_app, config, mode="wsgi")
259
```