Python 生成器和产量

问题描述 投票:0回答:2

我正在从前端发送一个请求到后端方法来触发,这里我的后端方法正在接收请求,所以在Python Flask后端方法中我使用生成器和yield来迭代一个包含100000个元素的列表,一一发送到前端,因此,通过前端后端方法的一个请求,应该向前端发送 10 万个响应..但我收到此错误标签:1 Access to XMLHttpRequest at 'http://0.0.0:3000/fetch_list' from origin “http://0.0.0.3000”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。

当我从前端生成器方法发送一个请求时,应该将响应一一发送到前端方法。 假设我在后端有一个列表,并迭代它使用yield将每个元素一个一个地发送到前端,直到列表的最后一个元素。如果列表包含 10 个元素,则应通过前端方法的一个 API 请求将 10 个响应发送到前端..提前致谢

这是我的前端方法

const fetchNumbers = async (): Promise<void> => {
    try {
        const response = awaitaxios.get(`http://0.0.0:3000}/fetch_list`);
        const data = response.data;
        console.log(data)
    } catch (error) {
        console.error(`Error occurred: ${error}`);
    }
};

后端 Flask python 代码:

@app.route('/fetch_list')
@cross_origin(origin="*", headers=["Content-Type"])
def generate_numbers():
    # Define a list of numbers
    print("Generate_numbers method is called")
    numbers = [i for i in range(1, 100001)]
    def generate():
        print("generate list")
        for num in numbers:
            yield jsonify({
                'number': num.flatten().tolist()
                })
            print(f"Sent number: {num}")
    return Response(generate(), content_type='application/json')
python typescript api flask
2个回答
1
投票

您的 IP 地址“0.0.0”中缺少 0 另外,我相信您正在寻找 flask 套接字 或在一个响应中发送列表,因为无法多次响应同一请求

另外:0.0.0.0 不是有效的 IP 地址,您应该使用 127.0.0.1 或服务器所在的任何主机


1
投票

将元素列表从 Flask 后端流式传输到前端客户端的目标是可以实现的,但在实现和期望中需要解决一些问题和误解:

CORS问题

您看到的错误与跨源资源共享 (CORS) 有关,这是网络浏览器中的一项安全功能。它可以防止网页向提供该网页的域以外的域发出请求。您的 Flask 应用程序需要在其响应中包含适当的 CORS 标头。

您正在使用 @cross_origin(origin="*", headers=["Content-Type"]) ,它应该允许任何域访问您的资源。但是,请确保您已在应用程序中正确配置 Flask-CORS。确保您已安装 Flask-CORS 并在 Flask 应用程序中初始化它:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

流式响应

对于流式传输大型数据集,您的后端方法几乎是正确的,但是您在生成器函数generate() 中使用 jsonify 将无法按流式响应的预期方式工作。 jsonify 通常用于返回 JSON 响应,但 Flask 无法像这样流式传输 jsonify 生成的响应列表。

相反,您应该手动构建 JSON 字符串或使用其他方法将数据序列化为 JSON,确保发送到客户端的每个块都是有效的 JSON 本身或连续 JSON 流的一部分。

前端处理

使用 HTTP 将数据从后端流式传输到前端并不简单,因为 HTTP 的设计目的不是按照您期望的方式处理单个请求的多个响应。使用 axios.get 的前端代码需要具有完整数据集的单个响应,而不是响应流。

对于从服务器到客户端的流数据,请考虑使用专为连续数据流设计的技术,例如 WebSocket 或服务器发送事件 (SSE)。两者都允许服务器通过单个长期连接将更新推送到客户端。

Flask 流响应示例

这是使用 Flask 的 Response 进行流式传输的后端的更正版本,请记住,这种方法通过单个 HTTP 响应以块的形式发送数据,并且您需要一种方法来在客户端正确处理此问题:

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

app = Flask(__name__)
CORS(app)

@app.route('/fetch_list')
def generate_numbers():
    numbers = range(1, 100001)  # Example range

    def generate():
        for num in numbers:
            # Manually construct JSON string for each number
            yield json.dumps({'number': num}) + "\n"  # Newline as   separator

return Response(stream_with_context(generate()), content_type='application/json')

此方法将每个数字作为单独的 JSON 对象进行流式传输,并以换行符分隔。但是,您需要调整前端来处理这种类型的流式响应。考虑使用支持流数据的库或 API,例如在客户端使用 fetch 和 ReadableStream,或者探索 WebSockets 或 SSE 以获得更强大的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.