File Uploads
Uploading files is a common feature in web apps. Flask makes it straightforward, but you need to handle security carefully. Never trust user-uploaded filenames - they could contain malicious paths.
First, configure your app to handle uploads. Set an upload folder and maximum file size:
import os
from flask import Flask, request
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = '/path/to/uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB limit
In your route, you access the uploaded file through request.files. This is a dictionary-like object with the file data:
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
if file:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return f'File uploaded: {filename}'
return render_template('upload.html')
See secure_filename()? This function sanitizes the filename, removing any path components and special characters. Always use it - without it, someone could upload a file like "../../etc/passwd" and overwrite system files.
You should also check file extensions to ensure only allowed types are uploaded:
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# In your upload route:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
In your template, create a form with enctype="multipart/form-data" and a file input:
<form method="POST" action="{{ url_for('upload_file') }}" enctype="multipart/form-data">
<input type="file" name="file" accept=".txt,.pdf,.png,.jpg,.jpeg,.gif">
<button type="submit">Upload</button>
</form>
The accept attribute is just a hint for the browser - your server-side validation is what really matters. Always validate on the server too.
For extra security, consider storing uploaded files outside your web root, scanning them for malware, and using random filenames to prevent guessing attacks.
Try it Yourself ->