Upload Files In Python Flask (Very Simple Example)

Welcome to a tutorial on how to upload files in Python Flask. Need to upload a file in Flask, but nothing just seems to work? Here is a quick sharing and simple example – Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Flask Upload Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

  • Create your own project folder, e.g. D:\upload, unzip the code inside this folder.
  • Open the terminal (or command line), navigate to your project folder cd D:\upload.
  • As usual, create a virtual environment if you don’t want to mess up your other projects.
    • virtualenv venv
    • Windows – venv\scripts\activate
    • Mac/Linux – venv/bin/activate
  • Get all the required packages – pip install Flask werkzeug
  • Launch! python s1_server.py and access http://localhost.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

PYTHON FLASK UPLOAD

All right, let us now walk through the steps of uploading a file in Python Flask.

 

PART 1) FLASK SERVER

1A) INIT

s1_server.py
# (A) INIT
# (A1) LOAD MODULES
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
 
# (A2) FLASK SETTINGS + INIT
app = Flask(__name__)
HOST_NAME = "localhost"
HOST_PORT = 80
app.config["UPLOAD_FOLDER"] = "uploads/"
# app.debug = True

The first section for the Flask server script should be self-explanatory. We are just loading the required modules (Flask) and defining a bunch of settings.

 

1B) HTTP ROUTES

s1_server.py
# (B) HTML UPLOAD PAGE
@app.route("/")
  def index():
  return render_template("s2_upload.html")
 
# (C) UPLOAD HANDLER
@app.route("/upload", methods = ["POST"])
def save_upload():
  if request.method == "POST":
    f = request.files["file"]
    filename = secure_filename(f.filename)
    f.save(app.config["UPLOAD_FOLDER"] + filename)
  return "UPLOAD OK"

Next, we define 2 “pages”.

  • / To serve the HTML upload form.
  • /upload To handle the upload itself.

P.S. We can do a one-line request.files["file"].save("UPLOADED.FILE") for convenience, but that secure_filename() is there to prevent… Funky things from happening.

 

 

1C) START

s1_server.py
# (D) START
if __name__ == "__main__":
  app.run(HOST_NAME, HOST_PORT)

Don’t think this needs any explanation.

 

PART 2) HTML UPLOAD PAGE

templates/s2_upload.html
<form action="http://localhost/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="file" required/>
  <input type="submit" value="Upload!"/>
</form>

This is just your “regular HTML file upload form”.

 

 

USEFUL BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

RESTRICTING FILE EXTENSIONS

HTML UPLOAD FORM

templates/s2_upload.html
<form action="http://localhost/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="file" required accept="image/*"/>
  <input type="submit" value="Upload!"/>
</form>

To restrict the file types we can simply add a accept="MIME TYPE" on the <input type="file"/> itself.

 

FLASK SERVER

s1_server.py
# DEFINE ALLOWED EXTENSIONS
ALLOWED_EXTENSIONS = {"txt", "pdf", "png", "jpg", "jpeg", "gif"}
 
# FUNCTION TO CHECK FILENAME
def allowed_file(filename):
  return "." in filename and \
    filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
 
# SAVE UPLOAD ONLY IF ALLOWED EXTENSION
f = request.files["file"]
if allowed_file(f.filename):
  filename = secure_filename(f.filename)
  f.save(app.config["UPLOAD_FOLDER"] + filename)

But the HTML restriction is not sufficient – It can be easily changed by users who know how to mess with the developer’s console. So here’s a small snippet from the Python manual itself, to add an “allowed extensions” check while uploading.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published.