cloudinary.exceptions.Error: Empty file using Flask - python

Im using cloudinary for upload file from my flask app.
I followed this basic sample code by pycloudinary for flask : https://github.com/cloudinary/pycloudinary/tree/master/samples/basic
but I still get the same error.
cloudinary.exceptions.Error
cloudinary.exceptions.Error: Empty file
My file post request with multipart-form and key name "image".
Before this, I already successfully upload file to static folder.
What should I do ?
def upload_files():
upload_result = None
file_to_upload = request.files['image']
if file_to_upload:
upload_result = upload(file_to_upload)
return "Success!"
else:
return "Failed!"

Should file_to_upload = request.files['image'] be
file_to_upload = request.files['file']?
request.files is a ImmutableMultiDict() that file is the key and not image.
Best,
Mo

Related

Using flask to run a python script

I have a script called output.py
This script takes in 2 inputs, fileA and file B.
I can run it on my terminal by using the command output.py -fileA -fileB. The script will create a new JSON file and save it to the directory.
I want to run this script using Flask. I've defined a bare bones App here but I'm not sure how I'd run this using Flask
from flask import Flask
import output
import scripting
app = Flask(__name__)
#app.route('/')
def script():
return output
if __name__ == '__main__':
app.run()
Can someone help me out here, thanks!
It appears you are new to Flask. Get some basic tutorials (there are many on the web).
There are a couple of options:
Send contents of file A and File b as json payload. Pull the A and B content off the json body and do the processing you need to and return the body.
Send the contents of the file as multipart/form-data (you can send multiple files).
Note: This is not working code - just for illustration.
from flask import Flask, request, make_response
app = Flask(__name__)
def build_response(status=False, error="", data={}, total=0, headers=[], contentType="application/json", expose_headers=["X-Total-Count"], retcode=400, additional_data=None):
resp = {"success": status, "error": error, "data": data}
resp = make_response(json.dumps(resp))
for item in headers:
resp.headers[item] = headers[item]
resp.headers['Content-Type'] = contentType
resp.headers.add('Access-Control-Expose-Headers', ','.join(expose_headers))
resp.status_code = retcode
return resp
#app.route('/run-script', methods=['POST'])
def run_script():
# check if the post request has the file part
try:
# Note: THis code is just to illustrate the concept.
# Option-1 (content type must be application/json)
json_dict = request.get_json()
fileA = json_dict["fileA"]
fileB = json_dict["fileB"]
# Option-2 (Note: fileA/fileB are objects, put a pdb and check it out)
fileA = request.files['fileA']
fileB = request.files['fileA']
resp = process(fileA, fileB)
return build_response(status=True, data=resp, retcode=200)
except Exception as e:
msg = f"Error - {str(ec)}"
return build_response(status=False, error=msg, retcode=400)

Flask downloads previous file version in response

I'm running a flask application that downloads a zip file that the user created.
The zipfile is deleted/overwritten with the same name for the user in the directory.
Then, when I get the download link, it downloads the old zipfile with the deleted files that cant be opened.
The link works correctly on incognito mode.
However in regular chrome, the request doesn't hit the test server before serving the zip file.
Anyone know what the issue might be?
#page.route('/response/<id>')
def response(id):
user = User.query.filter(User.spreadsheet_id.any(id)).first()
print(user.spreadsheet_id)
zip_name = f'{user.email}_zip.zip'
path = ''
root_dir = os.path.dirname(os.getcwd())
print(os.path.join(root_dir, 'app', zip_name))
return send_file(os.path.join(root_dir, 'app', zip_name), mimetype='zip', attachment_filename=zip_name, as_attachment=True)
in my case the solution was to wrap the attachment in a Response object and add a cache-control header:
attachment = send_file(os.path.join(root_dir, 'app', zip_name), mimetype='zip', attachment_filename=zip_name, as_attachment=True)
resp = make_response(attachment)
resp.cache_control.max_age = 120
return resp

how to upload local video to aws s3 using boto3 flask

I am new in flask.
I want to upload video in s3 aws using flask. Also, filename changes every time when a new file upload.
And there is subfolder in bucket like bucketname/videos I want to upload in videos
def uploadvideo():
finalResult = 'abc.mp4'
s3_bucket_video_url = 'media-storage-beta' + '/videos/' + 'video'
s3 = boto3.client('s3')
response = s3.upload_file(
finalResult, 'media-storage-beta', 'video')
return 'success'
You need to install boto3 in your virtualenv. Also depends where you are running Flask app. If you trying to upload from local. You need AWS access keys in the ENV variables. You can define a route like this in flask. A form with videotitle and upload file in form is used here.
#app.route('/uploadvideo', methods=['POST'])
def uploadvideo():
if request.method == 'POST':
print(request.form['videotitle'])
f_video = request.files['videofile']
print(f_video.filename)
# create video_url
s3_bucket_video_url = <Main_Folder> + '/videos/' + video_file_name
s3_client = boto3.client('s3')
response = s3_client.upload_file(
f.filename, <BUCKET_NAME>,s3_bucket_video_url)
return 'Success'
Thanks
Ashish

How to send GET/POST request on a flask based local website?

I have a website which takes a .txt file as input through an upload button. The backend model processes this text file and output a new .txt file. My website is working perfectly with the UI. But I was trying to send GET/POST request to my file using the curl command:
curl -F 'file=#CNN.txt' http://127.0.0.1:5000/
The output was that my whole html file got printed (as a cat command does) in the terminal.
I want to know how can I get the processed file using the curl command itself? I think to get the file, I need to return some kind of JSON object too. I am completely new to this stuff. Please bare with me.. My appy.py file is:
#app.route('/', methods = ['GET','POST'])
def hello():
if(request.method == 'POST'):
if('file' not in request.files):
return 'NO FILE'
file = request.files['file']
if(file.filename == ''):
print('NO FILES')
return redirect(request.url)
if(file and allowed_file(file.filename)):
uploadedFile = file.filename
file.save(os.path.join(UPLOAD_FOLDER, file.filename))
if(uploadedFile != ''):
neural_code_sum.starter(uploadedFile)
return render_template('index.html', message='success')
return render_template('index.html', message='NOT UPLOADED (ONLY .TXT FILES ALLOWED)')
#app.route('/download')
def download_file():
global uploadedFile
doc = os.path.dirname(os.path.realpath(__file__))+'/output.txt'
return send_file(doc,as_attachment=True,cache_timeout=0)
Just add GET above:
#app.route('/download', methods = ['GET'])
def download_file():
global uploadedFile
doc = os.path.dirname(os.path.realpath(__file__))+'/output.txt'
return send_file(doc,as_attachment=True,cache_timeout=0)
The first send the file: curl -F 'file=#CNN.txt' http://127.0.0.1:5000/
Then download it: curl http://127.0.0.1:5000/download -o output.txt
That's it! All the best.
#app.route('/download',methods=['**GET'**])
def download_file():
global uploadedFile
doc = os.path.dirname(os.path.realpath(__file__))+'/output.txt'
return send_file(doc,as_attachment=True,cache_timeout=0)
Add the method by which you want to send the request in the methods field.

Flask to read and write to same csv

I have a flask app that was created using a csv file. Using html forms, I give the user the option to input new data, and then I write changes to the csv (using a custom function) and download it. This downloads just fine and saves to my desktop. Is there any way to tweak the code to save it in the same project directory and overwrite the csv that serves the flask app? This way the app might update upon refresh. Thanks!
#app.route('/csv/')
def download_csv():
model_id=request.args['textid']
client_id = session['client_id']
# return response
df=recommender.update_history(client_id, model_id)
df= recommender.get_csv()
resp = make_response(df.to_csv(encoding='iso-8859-1',index=False))
resp.headers["Content-Disposition"] = "attachment; filename=export.csv"
resp.headers["Content-Type"] = "text/csv"
return resp
The comment above is correct. I didn't need the make_response function. Here's what worked:
#app.route('/csv/')
def download_csv():
model_id=request.args['textid']
client_id = session['client_id']
# return response
df=recommender.update_history(client_id, model_id)
df= recommender.get_csv()
path=r'data/file_name.csv'
resp = df.to_csv(path, encoding='iso-8859-1',index=False)
return render_template('index.html')

Categories

Resources