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