【问题标题】:Send numpy array as bytes from python to JS through Flask通过 Flask 将 numpy 数组作为字节从 python 发送到 JS
【发布时间】:2019-02-27 06:31:12
【问题描述】:

一个numpy数组应该通过flask从python发送到JS。我不想将它 jsonify 并发送,因为它会增加响应的大小并最终增加响应时间。所以我想我可以使用 tobytes() 将 numpy 转换为字节,通过烧瓶将字节发送到 JS,然后将字节转换回 JS 中的浮点数,发现Converting a string of packed bytes into an array of floats in Javascript 回答很有帮助。

操作列表是

byte_arr = np.array([5.6], dtype=np.float32).tobytes()  # Used one value just to make it simple
return byte_arr  # Bytes can be directly sent from flask as response

在 JS 中,

str = response.text
bytes = Uint8Array.from(str, c => c.charCodeAt(0))
floats = new Float32Array(bytes.buffer)

但是在 JS 中转换为浮点数时,我没有得到正确的值。调试时我发现在 JS 中 Uint8 数组中的某些值与从 python 发送的字节值不匹配。

JS: console.log(bytes)  // [51, 51, 255, 64]
Python: for val in byte_arr: print(val, end=" ")  // 51, 51, 179, 64

为了验证,我在 python 中创建了另一个客户端,发出相同的请求并将响应字节转换为浮点数。我在这里也遇到了同样的问题。所以我缩小了问题出在服务器端而不是在客户端。我在玩多个值时发现的一件更有趣的事情是,只有大于 127(我猜是这样)的数字才会转换为 255。

在尝试一些随机技巧时,我尝试在发送响应之前使用 python 的 chr() 方法将字节整数转换为字符,并且客户端的转换工作。

byte_arr = np.array([5.6], dtype=np.float32).tobytes()
byte_arr_char = "".join([chr(i) for i in byte_arr])
return byte_arr_char

但我的问题是,这是一个理想的解决方案,还是我在这里做一些修改以使其工作?谁能帮我理解为什么在没有 chr() 的情况下发送纯字节不起作用?

【问题讨论】:

  • 你能编辑成问题byte_arr在python中的值是什么,response.text在JS中的值是什么?
  • response 是如何收到的?你确定要set a suitable response type吗?
  • @CharlieWindolf 当然。但是 JS 脚本中的值都是问号。

标签: javascript python numpy flask data-conversion


【解决方案1】:

如果您没有明确设置MIME type,我认为Flask 会将其视为文本数据。您的浏览器似乎已经使用 ASCII 解码了二进制数据,这可以解释为什么只有大于 127 的值会受到影响。

因此,请尝试在 Flask 中设置响应的Content-Type

@app.route('/your/url/to/numpy/data')
def get_nparray():
    your_np_array = np.array([5.6], dtype=np.float32)
    response = flask.make_response(your_np_array.tobytes())
    response.headers.set('Content-Type', 'application/octet-stream')
    # response.headers.set('Content-Disposition', 'attachment', filename='np-array.bin')
    return response

或者,有一个辅助函数flask.send_file 可以在一行中构造响应。请找一个例子here

除了这个错误,还要注意你的二进制数据的endianness,这是硬件特定的。我建议您参考这个answerJavascript 类型数组和字节序)。

【讨论】:

  • 感谢您的回答。它按我想要的方式工作。另外,我了解了 send_file 的用法,但数据将作为图像接收,在这种情况下,我不确定如何将图像作为数组/文本接收。
  • 我实际上在这里遇到了另一个问题。我能够在 python 中得到正确的响应,但是在 JS 中我使用 angular 的 $http 来做出响应,我仍然遇到同样的问题。我得到的响应不是“应用程序/八位字节流”响应。这总结了问题github.com/angular/angular.js/issues/10349。有什么解决办法吗?
猜你喜欢
  • 2019-09-25
  • 2020-05-25
  • 1970-01-01
  • 2021-05-30
  • 2015-07-11
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多