记得之前有人问起,如果我的业务逻辑里面有很多任务,此时请求一个http接口,想要实现告诉一下前端当前执行任务的进度情况,这种处理机制是否能够实现。
按之前的分析,我之前给的方案是在完全在已知内容长度的情况下的方案,但目前有一个可以自定义的方式来告知当前。此方案其实就是分段传输。前面的一章有提到过。但是前面提到的时候,那种方式在浏览器上可以看到,但是使用API接口请求的时候则看不到,所以优化了以下。
实现的思路来自于以下代码:
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
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。