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 /syncorGET /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.
 
    