ITPub博客

首页 > 数据库 > 数据库开发技术 > fastapi框架源码分析系列-(10)给HTTP请求返回一个任务执行进度值(进度条的实现思路)

fastapi框架源码分析系列-(10)给HTTP请求返回一个任务执行进度值(进度条的实现思路)

原创 数据库开发技术 作者:程序员小钟同学 时间:2022-07-22 21:49:04 0 删除 编辑

1 实现HTTP进度条通知

记得之前有人问起,如果我的业务逻辑里面有很多任务,此时请求一个http接口,想要实现告诉一下前端当前执行任务的进度情况,这种处理机制是否能够实现。

按之前的分析,我之前给的方案是在完全在已知内容长度的情况下的方案,但目前有一个可以自定义的方式来告知当前。此方案其实就是分段传输。前面的一章有提到过。但是前面提到的时候,那种方式在浏览器上可以看到,但是使用API接口请求的时候则看不到,所以优化了以下。

2 优化代码实现

实现的思路来自于以下代码:

https://stackoverflow.com/questions/70037576/use-anyio-taskgroup-with-fastapi-streamingresponse

完整源码示例代码:

import anyio
from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()


@app.get("/")
async def root():
    #streaming_iter_data是协程函数对象,返回是一个异步的 typing.AsyncIterable
    return StreamingResponse(streaming_iter_data())

async def worker_process_send(send_msg_stream):
    async with send_msg_stream:
        for i in range(1,101):
            await anyio.sleep(1)
            await send_msg_stream.send(f"发送到前端的前端条的值是: {i}\n")

async def streaming_iter_data():
    # 创建一个内存对象流旨在实现具有多个任务的生产者-消费者模式。
    # 返回的是已使用,一对对象流:一个用于发送,一个用于接收。它们本质上像队列一样工作,但支持关闭和异步迭代。
    send_stream, receive_stream = anyio.create_memory_object_stream()
    async with anyio.create_task_group() as tg:
        # 开始执行生产者,也就是要发送消息的生产处理
        tg.start_soon(worker_process_send, send_stream)
        # 开始执行异步的迭代接收上面生产者生产的消息,并且通过yield的方法返回给出去
        async with receive_stream:
            async for entry in receive_stream:
                yield entry

if __name__ == "__main__":
    import uvicorn
    import os
    app_modeel_name = os.path.basename(__file__).replace(".py", "")
    print(app_modeel_name)
    uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)

客户端测试代码:

import requests

base_url="http://127.0.0.1:8000"

r = requests.get(base_url, stream=True)
# for chunk in r.iter_content(chunk_size=1024):
#  print("chunk:", chunk)
for lines in r.iter_lines():
 print("lines:", lines.decode(encoding='utf-8'))

客户端执行显示结果(每隔一秒):

lines: 发送到前端的前端条的值是:1
lines: 发送到前端的前端条的值是:2
lines: 发送到前端的前端条的值是:3
lines: 发送到前端的前端条的值是:4
lines: 发送到前端的前端条的值是:5
lines: 发送到前端的前端条的值是:6
lines: 发送到前端的前端条的值是:7
lines: 发送到前端的前端条的值是:8
lines: 发送到前端的前端条的值是:9
lines: 发送到前端的前端条的值是:10
lines: 发送到前端的前端条的值是:11
·····

如果我们需要在一个请求中处理多个任务函数的时候,可以在worker_process_send进行任务处理即可!以上仅仅是个人结合自己的实际需求,做学习的实践笔记!如有笔误!欢迎批评指正!感谢各位大佬!

结尾

END

简书:https://www.jianshu.com/u/d6960089b087

掘金:https://juejin.cn/user/2963939079225608

公众号:微信搜【程序员小钟同学】

小钟同学 | 文 【欢迎一起学习交流】| QQ:308711822


原文作者:程序员小钟同学;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2021-02-20

  • 博文量
    224
  • 访问量
    111682