FastAPI python: 如何运行 一个线程在后台?

FastAPI python: How to run a thread in the background?

我正在 python 使用 FastAPI 创建一个服务器,我想要一个与我的 API 无关的功能,以便在后台 运行每 5 分钟一次(例如检查 api 中的内容并根据响应打印内容)

我尝试创建一个线程,运行 函数启动 worker 但它不打印任何内容。

有人知道怎么做吗?

def start_worker():
    print('[main]: starting worker...')
    my_worker = worker.Worker()
    my_worker.working_loop() # this function prints "hello" every 5 seconds

if __name__ == '__main__':
    print('[main]: starting...')
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
    _worker_thread = Thread(target=start_worker, daemon=False)
    _worker_thread.start()

您应该在调用 uvicorn.run 之前启动线程,因为 uvicorn.run 正在阻塞线程。

PS:在您的问题中您声明您希望后台任务每 5 分钟 运行,但在您的代码中您说每 5 .下面的例子假设这是你想要的后者。如果您希望它每 5 分钟执行一次,则将时间调整为 60 * 5.

选项 1

import time
import threading
from fastapi import FastAPI
import uvicorn

app = FastAPI()
class BackgroundTasks(threading.Thread):
    def run(self,*args,**kwargs):
        while True:
            print('Hello')
            time.sleep(5)
  
if __name__ == '__main__':
    t = BackgroundTasks()
    t.start()
    uvicorn.run(app, host="0.0.0.0", port=8000)

您也可以使用 FastAPI 的 startup event 启动您的线程,只要在应用程序启动之前 运行 没问题。

@app.on_event("startup")
async def startup_event():
    t = BackgroundTasks()
    t.start()

选项 2

您可以改为对后台任务使用重复 Event scheduler,如下所示:

import sched, time
from threading import Thread
from fastapi import FastAPI
import uvicorn

app = FastAPI()
s = sched.scheduler(time.time, time.sleep)

def print_event(sc): 
    print("Hello")
    sc.enter(5, 1, print_event, (sc,))

def start_scheduler():
    s.enter(5, 1, print_event, (s,))
    s.run()

@app.on_event("startup")
async def startup_event():
    thread = Thread(target = start_scheduler)
    thread.start()

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