【问题标题】:FastAPI + uvicorn: Is it possible to accept multiple connections with a single worker?FastAPI + uvicorn:是否可以接受一个 worker 的多个连接?
【发布时间】:2023-02-11 22:57:51
【问题描述】:

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)
  1. Pick any endpoint above: GET /sync or GET /async
  2. Call the endpoint from two different web browser tabs (or use cURL, etc.) to create two parallel requests
  3. 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.

标签: python asynchronous async-await fastapi uvicorn


【解决方案1】:

从浏览器调用 Web 端点将被阻止(在客户端),因为它正在等待响应。为了正确测试它,您需要异步调用它。例如,您可以使用单独的 python 脚本

import asyncio
import aiohttp
from aiohttp import ClientSession

async def call_async(session: ClientSession, url: str):
    async with session.get(url) as result:

async def main():
    async with aiohttp.ClientSession() as session:
    url = 'https://localhost:5000/async'  # change port 
    tasks = [call_async(session, url) for i in range(5)]
    for finished_task in asyncio.as_completed(tasks):
        print(await finished_task)

asyncio.run(main())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 2020-07-14
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多