Here is some sample code to demonstrate the issue:
import asyncio
import datetime
import time
import uvicorn
from fastapi import FastAPI
from starlette.responses import PlainTextResponse
app = FastAPI()
@app.get(path="/sync")
def get_sync():
print(f"sync: {datetime.datetime.now()}: Before sleep")
time.sleep(5)
print(f"sync: {datetime.datetime.now()}: After sleep")
return PlainTextResponse(content=f"sync: {datetime.datetime.now()}: Hello, World!")
@app.get(path="/async")
async def get_async():
print(f"async: {datetime.datetime.now()}: Before sleep")
await asyncio.sleep(5)
print(f"async: {datetime.datetime.now()}: After sleep")
return PlainTextResponse(content=f"async: {datetime.datetime.now()}: Hello, World!")
if __name__ == "__main__":
uvicorn.run(app=app, host="0.0.0.0", port=1911)
- Pick any endpoint above:
GET /sync
orGET /async
- Call the endpoint from two different web browser tabs (or use cURL, etc.) to create two parallel requests
- The first request blocks the second request.
I expected GET /sync
to run on a threadpool. I expected GET /async
to use some asyncio magic.
I cannot use multiple workers. Is there a solution to allow concurrent requests with a single worker?
FYI: I am using Python 3.7 (64-bit/Win10) and latest versions of FastAPI + unvicorn.