отправка сжатого numpy массива (zlib) на flask сервер с помощью почтового запроса [python] - PullRequest
2 голосов
/ 27 мая 2020

Я пытаюсь отправить сжатый массив numpy (сжатый с помощью zlib) на сервер flask с помощью почтового запроса, но объект сжатых байтов изменяется на стороне сервера. Как правильно отправить объект байтов с запросом requests post, чтобы я мог распаковать на стороне сервера?

server.py

from flask import Flask
from flask_restful import Resource, Api, reqparse
import json
import numpy as np
import base64


# compression
import zlib

app = Flask(__name__)
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument('imgb64')

class Predict(Resource):
    def post(self):
        data = parser.parse_args()
        if data['imgb64'] == "":
            return {
                    'data':'',
                    'message':'No file found',
                    'status':'error'
                    }

        img = data['imgb64']

        print('rec')

        # decompress
        print(type(img))
        print(img)

        dec = zlib.decompress(img) # this gives me error



        if img:
            pass

            return json.dumps({
                    'data': 'done', 
                    'message':'darknet processed',
                    'status':'success'
                    })
        return {
                'data':'',
                'message':'Something when wrong',
                'status':'error'
                }


api.add_resource(Predict,'/predict')

if __name__ == '__main__':
    app.run(debug=True, host = '0.0.0.0', port = 5000, threaded=True)

client.py

import numpy as np 
import base64
import zlib
import requests

frame = np.random.randint(0,255,(5,5,3)) # dummy rgb image
# compress

data = zlib.compress(frame)
print('b64 encoded')
print(data)
print(len(data))
print(type(data))

r = requests.post("http://127.0.0.1:5000/predict", data={'imgb64' : data}) # sending compressed numpy array

Это дает мне следующую ошибку:

TypeError: a bytes-like object is required, not 'str'

Итак, я попытался преобразовать строку в объект bytes :

dec = zlib.decompress(img.encode()) # this gives me error

Но это тоже дает мне ошибку:

zlib.error: Error -3 while decompressing data: incorrect header check

Я пробовал с другими кодировками, они тоже не смогли .

Я заметил одну вещь: когда я печатаю сжатые байты на стороне клиента, он читает:

b'x\x9c-\xcf?J\x82q\x00\x06\xe0\x0ftrVP\\C\xf4\x06\x9268\t\xcdR\x8ej.F\xa0\xe0\xd0\xa6\xa3\xe0V\x07\x10\x1cL\xc8\xd1\x03\xd4\xe4\t\x0c\x12\x84\xb6D\x0c#\xbc\x80O\xf0\x1b\x9e\xf5\xfdS\x89\xa2h\xcf\x9a\x03\xef\xc4\xf8cF\x92\r\xbf4i\x11g\xc83\x0f\x8c\xb9\xa2@\x8e\x1bn\xd91g\xc0\x91%\xd7\xdc\xf3M\x83<i:L\xa8\xf1\x19\xfa\xffw\xfd\xf0\xc5\x94:O\x9cH\x85\xcc6#\x1e\xc3\xf6\x05\xe5\xa0\xc7\x96\x04]J\\\x90\xa1\x1f~Ty\xe1\x8d\x15w|P\xe4\x95K\xb2!\xe3\x0cw)%I'

Но на стороне сервера полученный строка совершенно другая:

�4ig�3���@�n�1g��%���M�<i:L����w��Ŕ:O�H��6#���ǖ]J\��~Ty�w|P�K�!�w)%I

Я также пытался отправить байты в виде строки,

r = requests.post("http://127.0.0.1:5000/predict", data={'imgb64' : str(data)})

Но я могу Не распаковывать данные на стороне сервера.

1 Ответ

0 голосов
/ 28 мая 2020

Кажется, я не могу отправить сжатые байты zlib напрямую, поэтому я использовал base64 для кодирования данных в строку ascii.

Итак, в целом это сработало для меня, numpy массив / любые нестроковые данные -> сжатие zlib -> кодирование base64 -> почтовый запрос -> flask -> декодирование base64 -> распаковка zlib

client.py

import numpy as np 
import base64
import zlib
import requests

frame = np.random.randint(0,255,(5,5,3)) # dummy rgb image

# compress

data = zlib.compress(frame)

data = base64.b64encode(data)


data_send = data

data2 = base64.b64decode(data)

data2 = zlib.decompress(data2)


fdata = np.frombuffer(data2, dtype=np.uint8)

print(fdata)


r = requests.post("http://127.0.0.1:5000/predict", data={'imgb64' : data_send})

server.py

from flask import Flask
from flask_restful import Resource, Api, reqparse
import json
import numpy as np
import base64


# compression
import zlib
import codecs


app = Flask(__name__)
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument('imgb64', help = 'type error')

class Predict(Resource):
    def post(self):
        data = parser.parse_args()
        #print(data)
        if data['imgb64'] == "":
            return {
                    'data':'',
                    'message':'No file found',
                    'status':'error'
                    }

        #img = open(data['imgb64'], 'r').read() # doesn't work
        img = data['imgb64']


        data2 = img.encode()
        data2 = base64.b64decode(data2)

        data2 = zlib.decompress(data2)

        fdata = np.frombuffer(data2, dtype=np.uint8)

        print(fdata)

        if img:

            return json.dumps({
                    'data': 'done', 
                    'message':'darknet processed',
                    'status':'success'
                    })
        return {
                'data':'',
                'message':'Something when wrong',
                'status':'error'
                }


api.add_resource(Predict,'/predict')

if __name__ == '__main__':
    app.run(debug=True, host = '0.0.0.0', port = 5000, threaded=True)
...