Falcon and falcon-multipart + POST request for uploading files implementation
Asked Answered
N

2

6

I'm trying to implement POST request for uploading files with Falcon framework (python).

I have used falcon-multipart in order to multipart/form-data, this allow me to retrieve my file in a cgi.FieldStorage() in which file is in binary format, but now, I need to write this file in a directory with the original extension.

This is the code I'm using.

app.py:

import falcon

from .files import Resource

from falcon_multipart.middleware import MultipartMiddleware

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

files = Resource()
api.add_route('/files', files)

files.py:

import io
import os
import shutil

import falcon
import json


class Resource(object):

   _storage_path = './uploaded_files'

   def on_post(self, req, resp):
        """
        POST METHOD
        """
        # Retrieve file extension
        ext = req.get_param('extension')

        # Retrieve input_file
        input_file = req.get_param('file')

        # Read file as binary
        raw = input_file.file.read()

        # Retrieve filename
        filename = input_file.filename

        # Define file_path
        file_path = os.path.join(self._storage_path, filename)

        # Write to a temporary file to prevent incomplete files from
        # being used.
        temp_file_path = file_path + '~'

        # Finally write the data to a temporary file
        with open(temp_file_path, 'wb') as output_file:
            shutil.copyfileobj(raw, output_file)

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

        resp.status = falcon.HTTP_201
Neper answered 23/2, 2018 at 3:12 Comment(0)
N
9

I had to study cgi

This is the implementation I used:

def on_post(self, req, resp):
        """
        POST METHOD
        """
        # Retrieve input_file
        input_file = req.get_param('file')

        # Test if the file was uploaded
        if input_file.filename:
            # Retrieve filename
            filename = input_file.filename

            # Define file_path
            file_path = os.path.join(self._storage_path, filename)

            # Write to a temporary file to prevent incomplete files
            # from being used.
            temp_file_path = file_path + '~'

            open(temp_file_path, 'wb').write(input_file.file.read())

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

    resp.status = falcon.HTTP_201
Neper answered 23/2, 2018 at 17:3 Comment(1)
This is NOT clear and not working for me - I would rather go for this oneBrecciate
A
0

Try this - more detail explained here

import io
import os
import uuid
import mimetypes
import falcon
import json

    


class Resource(object):
    
        _CHUNK_SIZE_BYTES = 4096
       
        def __init__(self, storage_path):
            self._storage_path = storage_path
    
        def on_post(self, req, resp):
            image = req.get_param("profilePic")
            # image_type = req.get_param("profilePic").type        
            ext = mimetypes.guess_extension(req.content_type)
            filename = "{uuid}{ext}".format(uuid=uuid.uuid4(), ext=ext)
            image_path = os.path.join(self._storage_path, filename)
            with open(image_path, "wb") as image_file:
                while True:
                    chunk = image.file.read(4096)
                    image_file.write(chunk)
                    if not chunk:
                        break
            resp.status = falcon.HTTP_200
            resp.location = filename
            resp.body = json.dumps("{name:" + image_path + "}")


import falcon
from falcon_multipart.middleware import MultipartMiddleware    

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

images = Resource('images')
api.add_route('/images', images)`
Adaxial answered 10/4, 2018 at 6:53 Comment(2)
please explain your code so everyone knows why it worksBeacon
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Querulous

© 2022 - 2024 — McMap. All rights reserved.