python-3.x 在main中使用www.example.com()时,无法访问API端点和swagger URLasyncio.run

w7t8yxp5  于 2022-12-30  发布在  Python
关注(0)|答案(1)|浏览(107)

在 asyncio.runmain中使用www.example.com(startup())时无法访问swagger端点http://127.0.0.1:8000/docs,但后台任务开始在后台运行。

app = FastAPI()

monitor_data = [
    {"url": "https://endpoint_1/", "type": "https", "Interval": 30},
    {"url": "https://endpoint_2/", "type": "https", "Interval": 60}
]

@app.get('/')
async def amialive():
    return "Live"

async def monitor(url, interval):
    while True:
        response = requests.get(url)
        print(f"{url}: {response.status_code})")
        await asyncio.sleep(interval)

async def startup():
    tasks = []
    for data in monitor_data:
        url = data["url"]
        interval = data["Interval"]
        task = asyncio.create_task(monitor(url, interval))
        tasks.append(task)
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(startup())
    # asyncio.create_task(startup()) 
    uvicorn.run("network_monitoring:app", host="0.0.0.0", port=8000 ,reload=True)

当我asyncio.run从main中删除www.example.com(startup())时,可以访问API端点,也可以 Swagger 。
有没有一种方法可以让我在脚本启动时运行后台任务并同时使用端点?thanks in advance.

bvjxkvbb

bvjxkvbb1#

您的函数startup等待monitor,这是一个无限循环,意味着asyncio.run(startup())将永远阻塞并运行。
要删除阻塞行为,只需删除monitor末尾的await asyncio.gather(*tasks),因为它的目的是创建后台任务,而asyncio.create_task会执行此操作,所以不需要它。
然而,这还不够,当调用uvicorn.run时,这将启动一个新的事件循环(甚至是一个新进程),而您希望在同一个事件循环中运行后台任务,为此,您可以使用FastAPI的startup事件:将启动装饰器@app.on_event("startup")添加到startup函数中

@app.on_event("startup")
async def startup():
    ...

if __name__ == "__main__":
    uvicorn.run("network_monitoring:app", host="0.0.0.0", port=8000, reload=True)

相关问题