To read the request body without blocking the asyncio task pool, you must fetch messages from the receive coroutine in a loop. Each message may contain a portion of the body and a more_body flag indicating if more data is coming.
async def read_body(receive):
"""
Read and return the entire body from an incoming ASGI message.
"""
body = b''
more_body = True
while more_body:
message = await receive()
body += message.get('body', b'')
more_body = message.get('more_body', False)
return body
async def app(scope, receive, send):
"""
Echo the request body back in an HTTP response.
"""
body = await read_body(receive)
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
(b'content-type', b'text/plain'),
(b'content-length', str(len(body)).encode())
]
})
await send({
'type': 'http.response.body',
'body': body,
})