通过python请求通过POST发送图像时,只有第一个字节到达

时间:2019-11-26 23:11:17

标签: python arrays post python-requests python-imaging-library

我目前正在尝试使用一些PIL图像为python flask服务器提供数据。发送请求的代码如下:

...
for i in range(0,1):  
  ...
  chip_gray = Image.fromarray(chip)
  display(chip_gray) #This displays correctly

  byteIO = io.BytesIO()
  chip_gray.save(byteIO, format='PNG')
  byteArr = byteIO.getvalue()
  print(byteArr) #This prints correctly
  length = len(byteArr)

  url = "http://facerec-server.herokuapp.com/add_custom"

  querystring = {"label": lfw_people.target_names[lfw_people.target[i]]}

  headers = {
      'Content-Type': "image/png",
      'Accept': "*/*",
      'Cache-Control': "no-cache",
      'Host': "facerec-server.herokuapp.com",
      'Accept-Encoding': "gzip, deflate",
      'Connection': "keep-alive",
      'Content-Length': str(length),
      'cache-control': "no-cache"
      }

  response = requests.request("POST", url, headers=headers, params=querystring, data={byteArr})

  print(response.text)

我已经按照测试并通过邮递员验证其工作方式的相同方式设置了结构。尽管出于某种原因使用了此代码(来自Google Colab的Ran),但只有第一个字节到达了服务器。这是在那里打印的内容:

2019-11-26T22:46:41.238471+00:00 app[web.1]: b'\x89'
2019-11-26T22:46:41.238626+00:00 app[web.1]: Host: facerec-server.herokuapp.com
2019-11-26T22:46:41.238628+00:00 app[web.1]: Connection: close
2019-11-26T22:46:41.238630+00:00 app[web.1]: User-Agent: python-requests/2.21.0
2019-11-26T22:46:41.238631+00:00 app[web.1]: Accept-Encoding: gzip, deflate
2019-11-26T22:46:41.238633+00:00 app[web.1]: Accept: */*
2019-11-26T22:46:41.238634+00:00 app[web.1]: Content-Type: image/png
2019-11-26T22:46:41.238635+00:00 app[web.1]: Cache-Control: no-cache
2019-11-26T22:46:41.238640+00:00 app[web.1]: X-Request-Id: dc61fe1e-5616-4b6d-8870-54b519be9f17
2019-11-26T22:46:41.238641+00:00 app[web.1]: X-Forwarded-For: 35.201.212.71
2019-11-26T22:46:41.238643+00:00 app[web.1]: X-Forwarded-Proto: http
2019-11-26T22:46:41.238644+00:00 app[web.1]: X-Forwarded-Port: 80
2019-11-26T22:46:41.238645+00:00 app[web.1]: Via: 1.1 vegur
2019-11-26T22:46:41.238646+00:00 app[web.1]: Connect-Time: 0
2019-11-26T22:46:41.238648+00:00 app[web.1]: X-Request-Start: 1574808401237
2019-11-26T22:46:41.238649+00:00 app[web.1]: Total-Route-Time: 0
2019-11-26T22:46:41.238650+00:00 app[web.1]: Content-Length: 1
2019-11-26T22:46:41.238746+00:00 app[web.1]: CombinedMultiDict([ImmutableMultiDict([('label', 'George W Bush')]), ImmutableMultiDict([])])
...
2019-11-26T22:46:41.239577+00:00 app[web.1]:   File "server.py", line 49, in method_custom
2019-11-26T22:46:41.239579+00:00 app[web.1]:     img = np.array(Image.open(io.BytesIO(r.data)))
2019-11-26T22:46:41.239580+00:00 app[web.1]:   File "/usr/local/lib/python3.6/site-packages/PIL/Image.py", line 2818, in open
2019-11-26T22:46:41.239581+00:00 app[web.1]:     raise IOError("cannot identify image file %r" % (filename if filename else fp))
2019-11-26T22:46:41.239583+00:00 app[web.1]: OSError: cannot identify image file <_io.BytesIO object at 0x7ff04408e0f8>
2019-11-26T22:46:41.240073+00:00 app[web.1]: 10.12.43.130 - - [26/Nov/2019 22:46:41] "[1m[35mPOST /add_custom?label=George+W+Bush HTTP/1.1[0m" 500 -

请注意,内容长度设置为1,只有第一个字节到达。

这是服务器上读取图像的代码(并与邮递员请求一起使用):

@app.route('/add_custom', methods=['POST'])
    def add_custom():
        print(request.data, flush=True)
        print(request.headers, flush=True)
        print(request.values, flush=True)
        start_time = time.time()
        data = np.array([method_custom(request)], dtype=np.float32)
        index_custom.add(data)
        index_ids_custom.append(request.args.get('label'))
        return Response(response=json.dumps({"time": (time.time() - start_time), "entries": len(index_ids_custom)}), status=200, content_type="application/json")

你们有谁知道这是为什么吗?

1 个答案:

答案 0 :(得分:1)

因此,您遇到的问题是Content-Length为1,这是服务器用来仅读取一个字节的内容。

您可以在客户端代码中打印标题以确保Content-Length不是1吗?另一种选择是停止自己设置Content-Length,因为请求可以为您完成设置。

现在让我们来看一下请求调用:

response = requests.request("POST", url, headers=headers, params=querystring, data={byteArr})

为什么要包装byteArr?我认为您实际上只是想在这里data=byteArr。另外请注意,requests.request("POST", ...)可以缩短为requests.post(...)