I started learning Flask by myself today, and while I was toying around with it I made a small program to download a file, and it worked great.
#app.route('/download')
def download():
path = "Path_to_my_file"
return send_file(path, as_attachment=True)
Now I was changing my program a bit and I removed the 'send_file' function and added some other commands. However, when I tried running the program, the download still happened. I have no idea why though.
My Code:
from flask import *
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename
import os
usera = ""
UPLOAD_FOLDER = 'I:/Python'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config ['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///downloads.sqlite3'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String)
download = db.column(db.String)
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
global usera, db
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
db.session.add(User(user = usera, download = filename))
return render_template('lol.html')
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/login',methods = ['POST', 'GET'])
def login():
global db, user
if request.method == 'POST':
usera = request.form['user']
return render_template('lol.html')
#app.route('/download')
def download():
path = "I:/Python/"
users = User.query.all()
return users
if __name__ == '__main__':
app.run(host='0.0.0.0')
I had faced same issue where flask was returning old files (in your case it is still sending files even if code is changed). This issue is due to the fact that file is cached in browser. Clear the browser cache and your api will start working.
Related
Im posting the following data to my flask image upload server. Problem is an image does not get saved. There are no errors in console.
I have tried decoding the image bytes and it seems to be a properly formed multipart request.
So why isn't the image uploading properly?
import os
from flask import Flask, flash, request, redirect, url_for, send_from_directory
import sys
UPLOAD_FOLDER = '/Users/admin/Desktop/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
print(request.get_data(), file=sys.stdout)
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
return redirect(url_for('uploaded_file',
filename=file.filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == "__main__":
# Quick test configuration. Please use proper Flask configuration options
# in production settings, and use a separate file or environment variables
# to manage the secret key!
app.secret_key = 'super secret key'
app.config['SESSION_TYPE'] = 'filesystem'
# sess.init_app(app)
app.debug = True
app.run()
Data im posting: (I captured it using print(request.get_data(), file=sys.stdout) located in code)
https://pastecode.io/s/cpev4ny4
could you please verify if your apache or whatever you use has permission to write ( save an image) in that directory?
I am trying to have users upload photos and then have those photos when submitted, go into a folder in pythonaywhere. I realized that even though the website is working, it seems as though my html and python code are not connected, hence why when I upload a pdf even if that is not an allowed extension, my webapp takes it in but it doesn't process through the conditions on my python code.
import os
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/home/HassanSherien/mysite/Shape_Image'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit a empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
flash(file)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',filename=filename))
elif request.method == "GET":
return render_template("overview_main_page.html", comments=Comment.query.all())
return
#app.route('/uploads/<filename>') #, #methods=["GET", "POST"])
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
<div class="w3-panel">
<div class="w3-row-padding" style="margin:0 -16px">
<div class="w3-third">
<form action="http://hassansherien.pythonanywhere.com" method="post">
<input type="file" name="file" value="fileupload" id="file_upload">
<input type='submit' />
I have a locally hosted Flask server and a small React application. I'm trying to use FilePond as an easy solution for image uploading. FilePond takes care of sending each image to the server.
So the problem I'm obviously having is with the backend code. I've set up my server like this, per Flask's docs
UPLOAD_FOLDER='/images'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
print(request.files)
if request.method == "POST":
# check if the post request has the file part
if 'file' not in request.files:
print('No file part')
return make_response("No File Part", 400)
file = request.files["file"]
# if user does not select file, browser also submit an empty part
# without filename
if file.filename == '':
print('No selected file')
return make_response("No Selected File", 400)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename) # filenames can be dangerous!
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return make_response("Success", 201)
However, when put a
print(request.files)
statement at the beginning of the upload_file() function, it seems that this is the request the server is receiving:
ImmutableMultiDict([('images', <FileStorage: 'imageName.jpg' ('image/jpeg')>)])
and I have no idea how to deal with that. I don't know if 'images' is where 'file' is supposed to be. I'm just not really sure where to go from here or what to do with the data being received. I don't know what is, I've never seen that <> syntax being used.
Can anyone help?
Here's a pastebin for the whole server-side code
Thank you!
Here's a proof of concept app that lets you upload multiple images using a form:
Note the enctype="multipart/form-data" attribute of the form, without this you cannot upload files.
Also note the multiple attribute of the file input. This allows client to select multiple files. You need to use request.files.getlist() to obtain the list of all uploaded files.
Once you generate the path to save the file, saving a werkzeug.FileStorage object is is just calling its .save(path_to_save) method.
from flask import Flask, request, render_template_string, redirect, abort
from werkzeug import secure_filename
from pathlib import Path
UPLOAD_DIR: Path = Path(__file__).parent / 'uploads'
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
app = Flask(__name__)
def is_valid_upload(upload) -> bool:
# some validation logic
return Path(upload.filename).suffix.lower() in ['.jpg', '.jpeg']
#app.route('/', methods=['GET', 'POST'])
def upload():
html = '''
<form action='/' method='POST' enctype="multipart/form-data">
<input type="file" name='images' multiple>
<button>Upload</button>
</form>
'''
if request.method == 'GET':
return html
uploaded_files = request.files.getlist('images')
if not uploaded_files or not uploaded_files[0].filename:
return redirect('/')
valid_uploads = list(filter(is_valid_upload, uploaded_files))
if not valid_uploads:
return 'invalid image(s)', 400
for upload in valid_uploads:
filename = secure_filename(upload.filename)
save_path = str(UPLOAD_DIR / filename)
upload.save(save_path)
return 'uploaded'
if __name__ == "__main__":
app.run()
Created a web app and have managed to build a function to clean up csv files from Google my Business exports. However when I run the function with the code I have written I get the following error message:
Not Found
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
Not sure where I am going wrong
mport os
import pandas as pd
from flask import Flask, request, redirect, url_for
from flask import Flask, make_response
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = './Downloads/gmbreports'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
ALLOWED_EXTENSIONS = 'csv'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def transform(text_file_contents):
disc = open('clean.csv')
disc2 = open('clean_two.csv','w')
#cleaning up csv
for row in disc:
row = row.strip()
row = row[1:-1]
row = row.replace('""','"')
disc2.write(row+'\n')
disc2.close()
disc.close()
discovery = pd.read_csv('clean_two.csv')
discovery_clean = discovery.iloc[1:]
cols = list(discovery_clean.columns[4:])
discovery_clean[cols] = discovery_clean[cols].apply(pd.to_numeric,errors='coerce')
return discovery_clean
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('You need to upload a csv file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',
filename=filename))
return '''
<!doctype html>
<title>Google My Business Discovery Report Builder</title>
<h1>Upload GMB Discovery csv</h1>
<form action="\transform" method="post" enctype="multipart/form-data">
<p><input type="file" name="file">
<input type="submit" value=Upload>
</form>
'''
#app.route('/transform',methods=["POST"])
def transform_view():
request_file=request.files['file']
request_file.save('clean.csv')
if not request_file:
return "No file"
result = transform()
print(result)
response = make_response(result)
response.headers["Content-Disposition"] ="attachment; filename=result.csv"
return response
if __name__=='__main__':
app.run()
Note: I get this error message after running the script and uploading a csv. The desired outcome is uploading a csv, and showing it on my screen as a cleaned up data table
There are multiple problems here. First, Wondercricket is correct about the form action. It needs to be changed to "/transform".
Once that's done, you're still getting an Internal Server Error. In this case, your transform function is defined as taking a single parameter, but it's not being called with one. Simply change
def transform(text_file_contents):
to
def transform():
That should allow the upload to happen, and the transform will now run. However, there's still one last problem. transform returns a pandas DataFrame, which Flask can't use as a response. Change
response = make_response(result)
to
response = make_response(result.to_csv())
and you should be good to go.
I'm following this tutorial on how to set up file uploading webservice using Flask. Below is a snipped of my code. I can see that the def upload_file(): gets the correct filename and allows it through, however, the line that actually saves the file does not get executed and I receive "Internal server error (500)" response. It seems that the issue is with actually storing files on disk.
What else do I need to do to set up my web service to save received files using Flask?
UPDATED - the code below works now
from flask import Flask
from flask import Response, jsonify, request, redirect, url_for
#persistent storage in dictionary
import shelve
#printing ip of host
import socket
#file uploading
import os
from werkzeug.utils import secure_filename
#serving files that were uploaded
from flask import send_from_directory
#mac-specific relative path to the script's location
UPLOAD_FOLDER = './audio'
ALLOWED_EXTENSIONS = set(['txt', 'm4a', 'mp4'])
#configuration
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
print 'upload file'
try:
os.stat(app.config['UPLOAD_FOLDER'])
except:
os.mkdir(app.config['UPLOAD_FOLDER'])
if request.method == 'POST':
file = request.files['file']
print 'filename: ' + file.filename
if file and allowed_file(file.filename):
print 'allowing file'
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
if __name__ == '__main__':
print(socket.gethostbyname(socket.gethostname()))
app.run(host='0.0.0.0')