【问题标题】:How to get Python FastAPI async/await functionality to work properly?如何让 Python FastAPI 异步/等待功能正常工作?
【发布时间】:2026-02-03 19:05:02
【问题描述】:

如何正确利用 FastAPI 路由中的异步功能?

以下代码 sn-p 需要 10 秒来完成对我的 /home 路由的调用,而我预计只需要 5 秒。

from fastapi import FastAPI
import time

app = FastAPI()

async def my_func_1():
    """
    my func 1
    """
    print('Func1 started..!!')
    time.sleep(5)
    print('Func1 ended..!!')

    return 'a..!!'

async def my_func_2():
    """
    my func 2
    """
    print('Func2 started..!!')
    time.sleep(5)
    print('Func2 ended..!!')

    return 'b..!!'

@app.get("/home")
async def root():
    """
    my home route
    """
    start = time.time()
    a = await my_func_1()
    b = await my_func_2()
    end = time.time()
    print('It took {} seconds to finish execution.'.format(round(end-start)))

    return {
        'a': a,
        'b': b
    }

我得到以下结果,看起来是非异步的:

λ uvicorn fapi_test:app --reload
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [5116]
INFO:     Started server process [7780]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:51862 - "GET / HTTP/1.1" 404
Func1 started..!!
Func1 ended..!!
Func2 started..!!
Func2 ended..!!
It took 10 seconds to finish execution.
INFO:     127.0.0.1:51868 - "GET /home HTTP/1.1" 200

但是,我希望 FastAPI 打印如下:

Func1 started..!!
Func2 started..!!
Func1 ended..!!
Func2 ended..!!
It took 5 seconds to finish execution.

如果我做错了什么请纠正我?

【问题讨论】:

标签: python fastapi


【解决方案1】:

time.sleep 被阻塞,你应该使用asyncio.sleep,还有.gather.wait 来聚合作业。这在 PythonFastAPI 中有详细记录。

【讨论】:

    【解决方案2】:

    可能有点晚了,从上面的Hedde's response 详细说明,这是您的代码应用程序的外观。 请记住在睡觉时await,并收集等待对象 - 如果您不这样做,无论您使用time.sleep() 还是asyncio.sleep(),您都将不会让这两个任务同时运行。

    from fastapi import FastAPI
    import time
    import asyncio
    
    app = FastAPI()
    
    async def my_func_1():
        """
        my func 1
        """
        print('Func1 started..!!')
        await asyncio.sleep(5)
        print('Func1 ended..!!')
    
        return 'a..!!'
    
    async def my_func_2():
        """
        my func 2
        """
        print('Func2 started..!!')
        await asyncio.sleep(5)
        print('Func2 ended..!!')
    
        return 'b..!!'
    
    @app.get("/home")
    async def root():
        """
        my home route
        """
        start = time.time()
        futures = [my_func_1(), my_func_2()]
        a,b = await asyncio.gather(*futures)
        end = time.time()
        print('It took {} seconds to finish execution.'.format(round(end-start)))
    
        return {
            'a': a,
            'b': b
        }
    
    

    【讨论】: