开发环境下,如何通过一个命令让 Fastapi 和 Celery 一起工作

开发 后端
FastAPI 是 Python Web 领域非常受欢迎的框架,目前 GitHub 上有 39.1k 的 star,已经远超过了 Django rest framework(22.3k star)。而 Celey 又是异步任务最流行的框架,常用于数据挖掘和机器学习等计算密集型任务的场景中。

[[439191]]

FastAPI 是 Python Web 领域非常受欢迎的框架,目前 GitHub 上有 39.1k 的 star,已经远超过了 Django rest framework(22.3k star)。而 Celey 又是异步任务最流行的框架,常用于数据挖掘和机器学习等计算密集型任务的场景中。如果需要通过 API 来异步调用任务,那这两个框架可以放在一起工作。本文来分享一下如何让 FastAPI 和 Celery 更好的相互配合,开发环境下如何通过一个命令就可以让两者一起工作。

0、安装依赖

  1. pip install fastapi celery uvicorn 

1、写个纯 celery 任务

首先,让我们来写一个纯属 celery 的任务,让它正常运行,然后在通过 fastapi 来调用它。

假设你的机器已经安装了 Python3 和 celery,并且本机已经开启了 redis,运行在 6379 端口上。

现在让我们写一个简单的任务:计算两数之和,文件名为:celery_app.py 代码如下:

  1. #!/Users/aaron/py38env/bin/python 
  2. # filename: celery_app.py 
  3. from celery import Celery 
  4.  
  5. app = Celery("tasks", broker='redis://127.0.0.1:6379/0', backend='redis://127.0.0.1:6379/0'
  6.  
  7. @app.task 
  8. def add(x, y): 
  9.     return x + y 

然后启动一个 worker 接收远程调用。

  1. celery -A celery_app worker -l info 

如果要远程异步调用这个 add 函数,我们需要再编写一个文件 start_celery_app.py,内容如下:

  1. from celery_app import add #导入我们的任务函数add 
  2. import time 
  3. result = add.delay(12,12) #异步调用,这一步不会阻塞,程序会立即往下运行 
  4.  
  5. while not result.ready():# 循环检查任务是否执行完毕 
  6.     print(time.strftime("%H:%M:%S")) 
  7.     time.sleep(1) 
  8.  
  9. print(result.get()) #获取任务的返回结果 
  10. print(result.successful()) #判断任务是否成功执行 

任务返回了结果 24,命令成功完成,

此时 worker 界面增加的信息如下:

2、通过 fastapi 来执行

编写一个 api.py 通过接口来调用上述的 add 函数:

  1. from fastapi import FastAPI 
  2. import celery_app 
  3.  
  4. app = FastAPI() 
  5.  
  6. @app.get("/"
  7. def read_root(): 
  8.     result = celery_app.add.delay(12, 12) 
  9.     return {"12+12": result.get()} 

启动服务:

  1. uvicorn api:app --host 0.0.0.0 --port 8000 --reload 

然后访问:http://127.0.0.1:8000,会发现任务成功执行:

这样我们启动了两个独立的进程,一个是 celery 的 worker,一个是 fastapi 的 app,这样做没问题,且生产环境下是严格要求分开运行的,不过,开发环境下如果这样做就太低效了。

3、开发环境下如何一条命令启动

如果不使用两个终端来启动两个命令,我们可以使用 Celery 提供的测试实用程序在后台线程中启动 celery worker,比如写一个这样的文件run.py,内容如下:

  1. import uvicorn 
  2.  
  3. original_callback = uvicorn.main.callback 
  4.  
  5. def callback(**kwargs): 
  6.     from celery.contrib.testing.worker import start_worker 
  7.     from celery_app import app 
  8.  
  9.     with start_worker(app, perform_ping_check=False, loglevel="info"): 
  10.         original_callback(**kwargs) 
  11.  
  12. uvicorn.main.callback = callback 
  13.  
  14.  
  15. if __name__ == "__main__"
  16.     uvicorn.main() 

这样,只需要执行一条命令就可以同时启动 celery worker 和 fastapi 接口服务,调试的时候是不是非常方便:图片

最后的话

 

本文分享了 fastapi 和 celery 是如何配合工作的,并分享了一个用于开发环境的脚本,可以通过一个命令来启动 celery worker 和 fastapi,可能不是完美的解决方案,但确实提升了开发效率,我觉得这是值得的,如果有帮助还请点赞、在看、关注,感谢阅读。

本文转载自微信公众号「Python七号」,可以通过以下二维码关注。转载本文请联系Python七号公众号。

 

责任编辑:武晓燕 来源: Python七号
相关推荐

2009-06-19 15:11:34

DWR和Spring

2022-06-06 09:00:00

Kubernete容器虚拟机

2011-01-20 11:42:49

同事

2020-10-12 08:02:04

开发人员开发编码

2013-08-19 11:31:43

2010-04-14 16:45:29

Oracle 9i全索

2011-07-25 09:14:40

程序员

2013-07-29 14:15:07

职场痛并快乐团队协作

2024-08-02 09:49:35

Spring流程Tomcat

2024-06-17 11:59:39

2015-10-20 16:48:06

AnsibleDocker可扩展设计

2022-10-08 07:55:33

DemoMongoDB异步

2023-04-11 07:48:32

WebGLCanvas

2024-08-29 09:18:55

2022-12-02 14:20:09

Tetris鸿蒙

2009-11-06 08:57:31

WCF开发

2021-10-27 06:49:34

线程池Core函数

2023-06-05 18:23:01

AI人工智能

2024-08-12 15:55:51

2022-08-29 07:48:27

文件数据参数类型
点赞
收藏

51CTO技术栈公众号