繁体   English   中英

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

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

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

我试图创建一个运行 function start_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 的启动事件来启动你的线程,只要在应用程序启动之前运行是可以的。

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

选项 2

您可以改为对后台任务使用重复事件调度程序,如下所示:

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)

@Chris 的解决方案正常工作!

但是,如果你想改进它并删除多余的start_scheduler方法,你只需要将sc参数直接传递给带有kwargs参数的print_event方法,如下所示:

import sched
import time
from threading import Thread

import uvicorn
from fastapi import FastAPI


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


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


@app.on_event("startup")
async def startup_event():
    thread = Thread(target=print_event, kwargs=dict(sc=s))
    thread.start()


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM