Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save an image from POST request with Falcon Python

I'm trying to find a way to save an image I get from a POST request, so far all the solutions I found ended up not working, for example, this.

The problem in which the above solution is that I just get a time out error.

I now tried to change the code a little bit but it is still not working, can you help me?

    def on_post(self, req, resp):
        """Handles Login POST requests"""
        json_data = json.loads(req.bounded_stream.read().decode('utf8'))
        base64encoded_image = json_data['image_data']
        with open('pic.png', "wb") as fh:
            fh.write(b64decode(base64encoded_image))

        resp.status = falcon.HTTP_203
        resp.body = json.dumps({'status': 1, 'message': 'success'})

The error I'm getting is "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"

like image 852
yarin Cohen Avatar asked Sep 11 '25 10:09

yarin Cohen


1 Answers

On your Falcon backend

Try falcon-multipart

pip3 install falcon-multipart

Then include it as your middleware.

from falcon_multipart.middleware import MultipartMiddleware

api = falcon.API(middleware=[MultipartMiddleware()])

This will parse any multipart/form-data incoming request, and put the keys in req._params, including files, so you get the field as other params.

# your image directory
refimages_path = "/my-img-dir"

# get incoming file
incoming_file = req.get_param("file")

# create imgid
imgId = str(int(datetime.datetime.now().timestamp() * 1000))

# build filename
filename = imgId + "." + incoming_file.filename.split(".")[-1]

# create a file path
file_path = refimages_path + "/" + filename

# write to a temporary file to prevent incomplete files from being used
temp_file_path = file_path + "~"
with open(temp_file_path, "wb") as f:
    f.write(incoming_file.file.read())

# file has been fully saved to disk move it into place
os.rename(temp_file_path, file_path)

On your frontend

Send Content-Type: multipart/form-data; in request header. Also do not forget to provide boundary because as specified in RFC2046:

The Content-Type field for multipart entities requires one parameter, "boundary". The boundary delimiter line is then defined as a line
consisting entirely of two hyphen characters ("-", decimal value 45)
followed by the boundary parameter value from the Content-Type header field, optional linear whitespace, and a terminating CRLF.

like image 174
kartoon Avatar answered Sep 14 '25 00:09

kartoon