我有一个用Python/Flask语言编写的API,它以字典/JSON列表的形式返回数据.它可以返回大量数据,所以我希望它能够将数据传输到客户端.我已经有了生成数据流所需的代码,我只需要弄清楚如何将该数据流提供给客户端.

我希望它是由客户端来决定,如果他们希望的结果流或不,即如果他们不流的响应,他们得到一个有效的列表的直接,但如果他们流的响应,他们会得到每个dict分隔的新行.

到目前为止,我的实现是旧的,基于这个blog post,正如博客更新中指出的,它不是很好:请求数据without streaming会导致一个正确的dict列表,但streaming it会导致一堆几乎可用的dict块.

我已经try 了以下新方法(我稍微简化了这个程序,这里data_generator迭代地提供了数据)

@app.route("/get_data", methods=["GET"])
def get_data(**kwargs):
    def stream_response():
        rows = data_generator
        for row in rows:
            yield json.dumps(row) + "\n"
    return Response(stream_response(), mimetype="application/json")

它通过dict工作并传输数据dict,但整个响应(未传输时)不是有效的、可解码的JSON.

是否有一种标准的方法来检测服务器端是客户端请求的数据流还是整个结果,以便在这两种情况下都可以返回有效的数据?我曾考虑过在API中添加一个参数或头,这样客户端就可以指定他们需要什么,但我希望有一个更"通用"的方法.

推荐答案

首先,它听起来像你的流数据使用的是JSON Lines格式.恐怕没有本地Flask对此的支持,但是知道这个名字可能有助于找到更多的资源.

是否有一种标准的方法来检测服务器端是否需要数据流

我不认为有一种可靠的方法来检测流媒体客户端.在发送响应正文的第一个字节之前,

我的建议是让客户发出信号,它想要哪一个.已经有一个完美的头球了,Accept: mimetype.

@app.route("/get_data", methods=["GET"])
def get_data(**kwargs):
    # Not an official mimetype, but already in use by AWS.
    if request.accept_mimetypes['application/jsonlines']:
        def stream_response():
            rows = data_generator
            for row in rows:
                yield json.dumps(row) + "\n"
        return Response(stream_response(), mimetype="application/jsonlines")
    else:
        # Send all data at once.
        return jsonify(list(data_generator))

然后,在流客户端,您必须设置Accept标头,如下所示(Javascript示例):

fetch('/get_data', {headers: {'Accept': 'application/jsonlines'}})

Python相关问答推荐

更改matplotlib彩色条的字体并勾选标签?

使用numpy提取数据块

Python daskValue错误:无法识别的区块管理器dask -必须是以下之一:[]

当多个值具有相同模式时返回空

Python json.转储包含一些UTF-8字符的二元组,要么失败,要么转换它们.我希望编码字符按原样保留

删除所有列值,但判断是否存在任何二元组

优化pytorch函数以消除for循环

大小为M的第N位_计数(或人口计数)的公式

将tdqm与cx.Oracle查询集成

Python导入某些库时非法指令(核心转储)(beautifulsoup4."" yfinance)

网格基于1.Y轴与2.x轴显示在matplotlib中

巨 Python :逆向猜谜游戏

使用tqdm的进度条

如何在Gekko中处理跨矢量优化

如何在信号的FFT中获得正确的频率幅值

如何编辑此代码,使其从多个EXCEL文件的特定工作表中提取数据以显示在单独的文件中

为什么我的scipy.optimize.minimize(method=";newton-cg";)函数停留在局部最大值上?

如果服务器设置为不侦听创建,则QWebSocket客户端不连接到QWebSocketServer;如果服务器稍后开始侦听,则不连接

启动线程时,Python键盘模块冻结/不工作

Scipy.linprog的可行性有问题吗?(A_ub@x0<;=b_ub).all()为True-但是-linprog(np.zeros_like(X0),A_ub=A_ub,b_ub=b_ub)不可行