将'print'猴补丁为'yield'以实现流输出
我正在使用一个运行时间很长的函数,这个函数主要是通过命令行界面(CLI)来调用的,状态是通过打印语句显示的。大概是这样的:
def long_running_function():
...
LOGGER.info("first thing done")
...
LOGGER.info("second thing done")
...
但现在我想从一个网页上触发同样的函数,并把这些打印语句实时发送到浏览器。
在FastAPI中,看起来我应该使用服务器推送事件(Server-Sent Events),但这需要一个能够生成消息的函数。像这样:
async def long_running_stream():
while True:
yield "data: message\n\n"
有没有办法把那些LOGGER语句改成'yield'语句?如果我在long_running_stream()里面调用long_running_function(),这样做会有效吗?
或者有没有更好的方法来实现这个?
1 个回答
有没有办法把那些 LOGGER 语句改成 'yield' 语句呢?
简单来说:没有。我假设你不能控制 long_running_stream
的实现。(如果你能完全控制,那你就可以随意修改了。)如果你把 LOGGER.info
函数进行猴子补丁(也就是修改它的行为),让它变成异步的,这样会立刻出错,因为 long_running_stream
不是异步的。
服务器发送事件(SSE)本身并不需要异步处理。像 FastAI 这样的库可能会用异步函数来生成它们,但这并不是必须的。同步的 API(比如 requests 库中使用的)也可以处理流(或者生成流)。当然,异步的 API 通常更合适。
我想从网页触发那个函数,并把打印的内容流式传输到浏览器。
我猜你的意思是,你想在服务器端触发那个函数,并把 SSE 从服务器流式传输到网页客户端/浏览器。关于这个的示例代码(同步和异步,使用 FastAI)可以在这里找到: https://www.workfall.com/learning/blog/how-to-stream-json-data-using-server-sent-events-and-fastapi-in-python-over-http/
那个特定的 long_running_function 可能不能直接使用。所以,你可能需要自己写一个事件生成器。