Not able to upload images with react-native and flask-restplus

92 Views Asked by At

I am trying to upload files with react-native in frontend and flask-restplus in backend but in flask-restplus parse_args function is giving error. I am able to upload a file with swagger window but getting error when passing formData from react-native android emulator. Can anybody suggest where I have done wrong coding.

React-native code snippet:

uploadImages = (image) => {
        const self = this;
        self.setState({isProgressShow: true});
        const {user, uploadType} = self.state;
        let formData = new FormData();
        formData.append('image', {
            name: image.fileName,
            type: image.type,
            uri: image.uri,
        });
        console.log(typeof(formData))
        uploadImage(formData)
            .then(response => {
                if (response.status === 200) {
                    console.log(response.data);
                    this.animate();
                    self.ocrRunCall(response.data, uploadType);
                }
            }).catch(error => {
            console.log(error);
            if (error.response !== undefined && error.response.status === 401) {
                logout();
                self.props.navigation.replace('Login');
            }
            if (error.response !== undefined && error.response.status === 500) {
                showMessage({
                    message: 'Please Try After Sometimes!!!',
                    type: 'danger',
                });
            }
            self.setState({isProgressShow: false});
            self.props.navigation.navigate('Home');
            showMessage({
                message: 'Please Try After Sometimes!!!',
                type: 'danger',
            });
        });
    };


export const uploadImage = async (formData) => {
    const token = await getApiKey();
    return await API({
        method: 'POST',
        url: `profile/uploadPicture`,
        data: formData,
        headers: {
            Authorization: token,
        },
    }).then((res) => {
        return res;
    });
};

python code snippet:

editPicture = reqparse.RequestParser()
editPicture.add_argument('image',location='files', type=FileStorage , required = True)
editPicture.add_argument('Authorization',type = str, location = 'headers', required = True)
@api.route("/uploadPicture")
class UploadPicture(Resource):
    @jwt_required()
    @api.doc(responses={ 200: 'OK', 400: 'Invalid Argument', 500: 'Mapping Key Error' })
    @api.expect(editPicture)
    def post(self):
        try:
            eh_user_id = get_jwt_identity()
            data = editPicture.parse_args()
            message = p.upload_image(eh_user_id,data)
            if message['flag']:
                return message, 200
            else:
                return message, 400

        except Exception as e:
            api.abort(500, e.__doc__, status = "Could not save information", statusCode = "500")

def upload_image(eh_user_id,data):
    
    try:
        res = {key : val for key, val in data.items() if val}
        user_params = list(res.keys())
        user_params.remove('Authorization')
        sec_filename = '' 
        f = data['image']      
        file_ext = os.path.splitext(f.filename)[1]
        save_file_path = utils.create_user_folders(eh_user_id,
        sec_filename = f.filename
        f.save(os.path.join(save_file_path[0],sec_filename))
        msg={'message':'file saved successfully'}
    except Exception as error:
        print("Details could not be saved : {}".format(error))
    return msg

error:
    data = editPicture.parse_args() # at this line
    raise self.mapping[code](*args, **kwargs)
    werkzeug.exceptions.InternalServerError: 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
1

There are 1 best solutions below

1
sonali patra On

I submitted this question a month ago but no body answered. I am answering my own question as I found a solution.

To upload images or videos in flask_restplus which can be used by react-native developers we can convert the data to base64 and pass it to python code which is a easier way to upload images, audio or video.

react-native code:

uploadImages = async (image) => {
        const self = this;
        
        const token = await getApiKey();
                const body={
            "file_upload":image.base64,
            "document_type":"jpg"
        }
                axios.post('http://ip-address:port/upload', body,
            {
                headers: {
                    'Content-Type': 'multipart/form-data',
                    Authorization: token,
                },
            }).then(response => {
            if (response.status === 200) {
                console.log(response.data);
            }
        }).catch(error => {
            console.log(error);
        });
    };

python code:

file_upload = reqparse.RequestParser()
file_upload.add_argument('base64_code',  required = True)
file_upload.add_argument('document_type',  required = True)
file_upload.add_argument('Authorization',type = str, location = 'headers', required = True)
@api.route("/documents_upload")
class EntityType(Resource):
    @jwt_required()
    @api.doc(responses={ 200: 'OK', 400: 'Invalid Argument', 500: 'Mapping Key Error' })
    @api.expect(file_download)
    def post(self):
        try:
            eh_user_id = get_jwt_identity()
            if eh_user_id:
                args = file_upload.parse_args() 
                message = file_upload_data.file_upload(eh_user_id,args)
                if message['flag']: 
                    return message, 200
                else:
                    return message, 400
                 
            
        except Exception as e:
            api.abort(500, e.__doc__, status = "Could not save information", statusCode = "500")

file_upload_data.py ###########################################################################

import base64

def file_upload(eh_user_id,data):
    bin_code=str(data["base64 code"])
    print("----------------------")
    bin_code=bin_code[2:-1]
    bin_code=bin_code.encode('utf-8')
    file_type=data["document type"]
    
    save_file_path = utils.create_user_folders(eh_user_id,["DOWNLOAD"])
    file_name="IMG"+'_'+datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")+'_'+str(eh_user_id)+"."+file_type
    sec_filename = secure_filename(file_name)
    file=open(os.path.join(save_file_path[0],sec_filename),"wb")
    file.write(base64.b64decode(bin_code))
    file.close()
    return {"flag":True,"message":"image downloaded"}

####utils.py

import os


    def create_user_folders(eh_user_id,subfolders):
        # TO create folders for storing Photo, UID, Prescription, Diagnostic reports
        try:
            #cwd = str(os.getcwd())
            root_path = "static/UserData/" +str(eh_user_id)
            print("create folder , rootpath is ",root_path)
            list_url = []
            print("subfolder is :",subfolders)
            print("final loc is ",root_path+subfolders[0])
            for c in subfolders:
                print("c is: ",c)
                path = os.path.join(root_path, c)
                print("path is: ",path)
                os.makedirs(path, exist_ok=True)
                list_url.append(path)
            print("create folder , list_url is ",list_url)
            return list_url
    
        except OSError as error:
            print("Directory '%s' can not be created:{}".format(error))