Flask框架进阶-Flask流式输出和受访配置--纯净详解版

Flask流式输出🚀

       在工作的项目当中遇到了一种情况,当前端页面需要对某个展示信息进行批量更新,如果直接将全部的数据算完之后,再返回更新,则会导致,前端点击刷新之后等待时间过长,开始考虑到用进度条或者流式输出的方式,但是由于进度条的计算前端页面的设计都需要改动会增加额外的工作量,因此考虑使用流式输出的方式,前端接收一个或一部分更新一个或一部分,因此就需要用到Flask框架中的流式输出的功能,其次,例如如果想要自己实现大语言模型的流式输出的效果,那这也是一项绕不开的学习点。

Flask框架初探-如何在本机发布一个web服务并通过requests访问自己发布的服务-简易入门版


文章目录

  • Flask流式输出🚀
  • 1.Flask流式输出基础代码+浏览器访问
  • 2.使用requests库接收流式输出的返回
  • 3.设置跨域
  • 4.设置响应头和响应类型
  • 5.设置SSE格式输出
  • 结束

1.Flask流式输出基础代码+浏览器访问


       Flask作为服务端的基础代码如下,先从简单的开始,下面会对代码中的部分再进行解释:

import time

from flask import Flask, Response
app = Flask(__name__)

@app.route('/stream')
def stream_numbers():
    def generate_numbers():
        for number in range(1, 10):
            yield f"{number}\n"  # 每次生成一个数字就发送 \n 最好不要删除
            time.sleep(0.5)  # 为了演示,加入短暂延迟

    return Response(generate_numbers())


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

       先给出直接使用浏览器的访问结果。这里我也观察到了好像是从2开始流输出,似乎是前一秒的数据会先缓存然后直接打印出来,然后后面的再正常流式输出,如果是用代码的话几乎不会有这个问题。
在这里插入图片描述

2.使用requests库接收流式输出的返回


       在python中可以使用通过requests库来接收流式输出的web服务格式,下面给出代码,运行下面代码之前别忘了把启动Flask服务的代码先运行起来。

import requests

def stream_from_server(url):
    response = requests.get(url, stream=True)  # Ensure you set stream=True
    for message in response.iter_lines():
        print("Received:", message.decode())

if __name__ == "__main__":
    stream_from_server("http://localhost:5000/stream")

在这里插入图片描述

3.设置跨域


跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种安全功能,它允许一个网页的资源能够被其他域名(origin)的网页访问。默认情况下,浏览器的同源策略会阻止从一个域中加载的网页去请求另一个域的资源。这是为了防止恶意网站访问或操作用户数据。

       由于目前公司里前端的同事使用的都是js,在使用js访问我们python的服务的时候,有很多奇怪的现象,如果我如果不开跨域,js的同事也能访问到我的数据,但实现不了流式输出的格式,等等,因此在开发python服务的时候,开着跨域能节省很多麻烦。在python中实现跨域需要安装一个新的库。flask_cors。

pip install flask_cors

在安装成果之后从flask_cors导入CORS然后给app套一层CORS(app, resources="/*")就可以实现跨域resources这个是设置允许跨域访问我们的地址,设置成"/*"表示允许所有地址k跨域访问我们。

from flask import Flask, Response
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources="/*")

完整代码如下:

import time
from flask import Flask, Response
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources="/*")

@app.route('/stream')
def stream_numbers():
    def generate_numbers():
        for number in range(1, 10):
            yield f"{number}\n"  # 每次生成一个数字就发送
            time.sleep(0.5)  # 为了演示,加入短暂延迟

    return Response(generate_numbers())


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

4.设置响应头和响应类型


js前端对于接收我们的要求非常苛刻,跨域开了之后,要服务器发送事件(Server-Sent Events, SSE)输出,还要响应头的内容类型对上,然后还得再响应头里把,时间类型,是否缓存,是否有响应缓冲都设置上,才能确保正常显示流式输出操作,增加了响应头和配置响应头相关内容的代码如下。

import time
from flask import Flask, Response
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources="/*")

@app.route('/stream')
def stream_numbers():
    def generate_numbers():
        for number in range(1, 10):
            yield f"{number}\n"  # 每次生成一个数字就发送
            time.sleep(0.5)  # 为了演示,加入短暂延迟
    headers = {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'X-Accel-Buffering': 'no',
    }
    return Response(generate_numbers(),headers=headers)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

响应头中的配置的内容解释如下。

  1. Content-Type: text/event-stream(必须要):
    • 这个响应头对于服务器发送事件(SSE)至关重要,这是一种从服务器向客户端推送事件的标准方式。它告诉客户端响应是一个事件流,客户端应该保持连接打开,并准备接收多个事件。
  2. Cache-Control: no-cache(必须要):
    • 这个头部指示浏览器或其他中间代理不要缓存当前的响应。在实时数据传输和事件流中,保证客户端接收的是最新的数据非常重要,而不是从缓存中提取的可能已经过时的数据。
  3. X-Accel-Buffering: no(这个看情况使用):
    • 这是一个非标准的响应头,主要用于控制Nginx反向代理服务器的缓冲行为。设置为no意味着禁止Nginx缓冲这个响应,这对于实时数据流非常重要,因为缓冲可能会导致数据延迟到达客户端。这个设置确保数据能够尽可能快地直接传输给客户端。

5.设置SSE格式输出


然后SSE格式的输出说明参考GPT-4。


       服务器发送事件(Server-Sent Events, SSE)是一种允许服务器主动向浏览器或客户端发送信息的技术。SSE 通常用于创建到服务器的单向持久连接,服务器可以通过这个连接发送任意数量的消息。这种方法主要用于实时应用,如实时通知、股票行情更新等。

SSE 数据的格式比较简单,以下是一个基本的示例:

data: This is a message

       每条消息都以一个或多个以 “data:” 开头的行组成,后面跟随实际的消息内容,最后以一个空行结束,表示消息的结束。客户端会在收到空行后处理消息。

       除了基本的消息外,SSE 还支持为消息指定事件类型和ID,这样客户端可以更精确地控制不同类型的消息处理。以下是一个包含事件类型和ID的完整示例:

plaintextCopy codeid: 1
event: user-update
data: { "username": "alice", "time": "2024-04-28T12:34:56Z" }
  • id: 这个字段是可选的,用于设置消息的唯一标识。在客户端断开连接后重新连接时,可以通过发送最后接收到的ID来请求服务器发送丢失的消息。
  • event: 也是可选的,指定事件的类型。客户端可以基于事件类型来决定如何处理接收到的数据。
  • data: 包含实际的消息内容。如果消息数据跨多行,每一行都需要以 “data:” 开始。

在上述代码的基础上我们要进行如下的改动,才能保证js使用EventSource接口接收正常。

  1. 将输出整体改成SSE格式
  2. 将SSE各种中的data变为json格式
  3. 再返回完主要内容之后最后还要额外返回一次done给出截至条件。

json.dumps()将字典转换为json格式

import json
import time

from flask import Flask, Response, json
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources="/*")

@app.route('/stream')
def stream_numbers():
    def generate_numbers():
        for number in range(1, 10):
            json_data = json.dumps({"number": number})
            yield f"data: {json_data}\n"  # 每次生成一个数字就发送
            time.sleep(0.5)  # 为了演示,加入短暂延迟
        json_data = json.dumps({"number": "done"})
        yield f"data: {json_data}\n"  # 发送完成信号

    headers = {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'X-Accel-Buffering': 'no',
    }

    return Response(generate_numbers(), headers=headers)



if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

接收结果:
在这里插入图片描述

结束


       以上技术就是实现一个自己的网页然后模拟ChatGPT流式输出的一块重要拼图,目前找了我的一个学弟用vue负责做前端,去做一下这个小项目,已经基本完成,之后会开源前后端代码和gitee的地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/582305.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑录制视频快捷键,一键开启录屏新时代(干货)

“最近尝试录制一些电脑上的操作视频,用来制作教学教程。不过,每次录制都要通过菜单或搜索来打开录屏软件,实在是有些繁琐。有没有人知道哪些电脑录制视频的快捷键呀?或者有没有通用的快捷键设置方法?” 在当今数字时…

CMake+qt+Visual Studio

#使用qt Creator 创建Cmake 项目,使用Cmake Gui 生成sln 工程,使用Visual Studio 开发 ##使用qt Creator 创建CMake项目 和创建pro工程的步骤一致,只是在选择构建系统的步骤上选择CMake,接下来步骤完全相同 工程新建完成之后,构建cmake 项…

PE文件(三)节表作业

本次作业以notepad进行演示,如下是其在硬盘上的内存 1.手动解析节表 由标准pe头可知,一共由7个节也就是7个节表,可选pe头的大小是0X00F0,即240字节大小 根据上述我们所获取的信息,找到节表的首地址为0x01F8 .text …

微服务:Nacos注册中心

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Nacos注册中心 一、服务注册与发现1.启动Nacos…

Vite proxy-rewrite 属性详解

在前端开发中,为了避免跨域问题,我们会在vite.config.ts 中配置如下问题 rewrite: 由于不了解Nginx的知识,这个属性一直困扰着我,这个重写有啥用,加和不加有啥影响 server: {host: 0.0.0.0,proxy: {/api: {target: ht…

手机通讯录删除了怎么恢复?这里几个方法超快找回!

当我们不小心删除了手机通讯录中的联系人,或者手机丢失导致通讯录信息丢失,恢复通讯录就变得非常重要了。手机通讯录删除了怎么恢复?我们该如何快速找回这些重要的联系人信息呢?下面我们将介绍2种简单易行的方法,帮助您…

Spark核心名词解释与编程

Spark核心概念 名词解释 1)ClusterManager:在Standalone(上述安装的模式,也就是依托于spark集群本身)模式中即为Master(主节点),控制整个集群,监控Worker。在YARN模式中为资源管理器ResourceManager(国内…

树莓集团整合行业资源 优化数字产业生态圈

树莓集团,作为国际数字影像产业园的运营方以及链主企业,自创立以来,一直致力于整合行业优质资源,为数字科技领域的优秀企业提供一片肥沃的创新土壤。随着信息技术的迅猛发展和数字经济的深入推进,树莓集团深知自身的责…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统,恢复出厂开箱状态一模一样 适用型号:隐星P16 23 链接:https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码:ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

机器学习在医疗行业的应用:颠覆传统诊疗模式,开启智慧医疗新时代

文章目录 一、精准诊断的突破二、药物研发的革新三、患者管理的智能化四、智能辅助决策系统五、机器学习在医疗行业的前景 随着科技的飞速发展,机器学习作为人工智能的核心技术,正逐渐渗透到各个行业中,其中在医疗行业的应用尤为引人瞩目。机…

Strassen矩阵乘法——C++

【题目描述】 根据课本“Strassen矩阵乘法”的基本原理,设计并实现一个矩阵快速乘法的工具。并演示至少10000维的矩阵快速乘法对比样例。 【功能要求】 实现普通矩阵乘法算法和“Strassen矩阵乘法”算法对相同的矩阵,分别用普通矩阵乘法算法&#xff…

电机控制系列模块解析(11)—— 电流采样

一、电流采样分类 由下图可知,采样电阻的位置不同,电流采样分为输出电流采样、下桥电流采样、母线电流采样。 输出电流采样 定义:输出电流采样是指对电机定子绕组或转子绕组(对于内转子永磁同步电机)输出的电流进行测…

什么是区块链?智能合约有什么用?

一、什么是区块链? 区块链是一种去中心化的分布式账本技术,通过加密和共识机制确保数据的安全和透明。它将交易数据按照时间顺序记录在区块中,并通过链式链接保证了数据的不可篡改性。 二、什么是智能合约? 智能合约是运行在区…

如何修改php版本

我使用的Hostease的Windows虚拟主机产品,由于网站程序需要支持高版本的PHP,程序已经上传到主机,但是没有找到切换PHP以及查看PHP有哪些版本的位置,因此咨询了Hostease的技术支持,寻求帮助了解到可以实现在Plesk面板上找到此切换PHP版本的按钮…

linux tcpdump的交叉编译以及使用

一、源码下载 官网:点击跳转 二、编译 1、解压 tar -xf libpcap-1.10.4.tar.xz tar -xf tcpdump-4.99.4.tar.xz 2、配置及编译 //libpcap: ./configure --hostarm-linux --targetarm-linux CCarm-linux-gcc --with-pcaplinux --prefix$PWD/build//t…

37 线程控制

内核中没有明确的线程的概念,线程作为轻量级进程。所以不会提供线程的系统调用,只提供了轻量级进程的系统调用,但这个接口比较复杂,使用很不方便,我们用户,需要一个线程的接口。应用层对轻量级进程的接口进…

企业如何保证内部传输文件使用的工具是安全的?

企业内部文件的频繁交换成为了日常运营不可或缺的一环。然而,随着数据量的爆炸式增长和网络攻击手段的日益复杂,内网文件传输的安全隐患也日益凸显,成为企业信息安全的薄弱环节。本文将探讨内网文件传输的安全风险、企业常用的防护措施。 内网…

Python轻量级Web框架Flask(12)—— Flask类视图实现前后端分离

0、前言: 在学习类视图之前要了解前后端分离的概念,相对于之前的模板,前后端分离的模板会去除views文件,添加两个新python文件apis和urls,其中apis是用于传输数据和解析数据 的,urls是用于写模板路径的。 …

终于有人把无人机5G通信原理讲清楚了

在现代科技快速发展的背景下,无人机技术在各个领域都有了广泛应用,从送外卖到农业监控,无人机正变得越来越普遍。然而,无人机的效能很大程度上受到其通信系统的限制,尤其是在城市这种高楼林立、障碍物众多的环境中。为…