or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-wrappers.mdasync-integration.mdconfiguration.mdevents.mdindex.mdlogging.mdmiddleware.mdserver-execution.mdtypes.mdutilities.md

async-integration.mddocs/

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

```