Python REST API with Flask – Part 2 – File upload and static file serve

In my previous article, REST API  with Python Flask gives an introduction to what REST architecture means and how Python framework can be used to create APIs and easily expose them to the web for others to use.  It is the beginning. If you have read it, then you would have known how to create a sample Flask application and expose a few APIs as POST and GET calls. It’s pretty simple.

In this article, we proceed further with exploring more functionality of Flask. The functionalities we are going to look at is serving static content to the web and how to accept files, or how to give an upload functionality with Flask.

We will build on the code that we have written in the previous article. So, let’s begin.

Serving Static Files

When you are building APIs, there might arise situations where you need to send files to the UI. For example, say, you want to send an Image or an HTML file or any other file. Usually, the user would get a link to a file like for example “https://sourcedexter.com/wp-content/uploads/2017/07/typing_python-course.png”. As you can see, this image is a static content, which you can view if you click the link. In other words, it can be called as a download link.

To achieve this in flask it is pretty simple.

Flask has an inbuilt method “send_from_directory” that you can use to send files. Firstly, create a folder called “static” in the root folder of your flask application.

Once that is complete, you can use the following code. (See the code comments to understand what the code is doing)

from flask import Flask, request, send_from_directory

# set the "static" directory as the static folder.
# this will ensure that all the static files are under one folder
app = Flask(__name__, static_url_path='/static')

# serving some static html files
@app.route('/html/path:path')
def send_html(path):
return send_from_directory('static', path)

if __name__ == "__main__":
app.run()

In the above code, if you created another folder within a static folder called “html” and put some files in it,
you can access the files using the URL “http://localhost:5000/html/test.html”. Of course, replace test.html with the file name that you have created.

So, you can replicate this by creating any number of folders within a static folder and also writing a method to handle that URL pattern.  It is also possible to have files directly in the static folder itself without having to create more internal folders.

Uploading files with Flask

Just like many other functionalities, providing an upload feature in Flask is very easy. There are two components involved here. First is the UI which will send the files to the flask backend. Second is the Flask application that accepts the files and stores it or does something else with it.

Sending files from the UI

The UI should send the files as a multipart-form-data. This feature allows a user to click a button and select a file which will then be sent to the backend.

If you are interested in implementing this functionality in the UI  you can refer to this guide. It shows how to implement the upload functionality using html5.

Upload file handler in Flask

Assuming that the UI is present and can send files to the backend, you can have a handler in Flask to accept the file and perform operations on it.

@app.route('/upload', methods=['POST'])
def upload_file():

print request.files
# checking if the file is present or not.
if 'file' not in request.files:
return "No file found"

file = request.files['file']
file.save("static/test.jpg")
return "file successfully saved"

In the code above we use the “request.files” to access all the files which have been uploaded. This means that the POST request can take more than one file and process it. The code above accesses the file and stores it in the static file directory that we had created earlier.

I have tested this code with the help of a tool called Postman. Image below:

Python rest APi with flask

If you are interested in learning about Flask in depth, then this course REST APIs with Flask and Python is the best one for you. It takes you through the basic as well as all the advanced topics in Flask in a structured project oriented approach.

Advertisements

akshay pai

I am a data science engineer and I love working on machine learning problems. I have experience in computer vision, OCR and NLP. I love writing and sharing my knowledge with others. This is why I created Source Dexter. Here I write about Python, Machine Learning, and Raspberry Pi the most. I also write about technology in general, books and topics related to science. I am also a freelance writer with over 3 years of writing high-quality, SEO optimized content for the web. I have written for startups, websites, and universities all across the globe. Get in Touch! We can discuss more.

5 thoughts on “Python REST API with Flask – Part 2 – File upload and static file serve

  • October 17, 2017 at 4:09 pm
    Permalink

    I don’t know why, but the API cant find the “test.html” file on html folder…
    Look the log error:
    127.0.0.1 – – [17/Oct/2017 08:36:20] “GET /html/test.html HTTP/1.1” 404 –
    Have you any tip?

    Reply
    • October 17, 2017 at 10:00 pm
      Permalink

      There was an error in the code, lt;path:path:gt; should have been something else. I have made the changes. You can make this change as well and I think your issue will be solved.

      Reply
  • May 8, 2018 at 6:40 pm
    Permalink

    Using Flask 1.0.2, I get an error when sending a file with Postman.

    The console prints:
    127.0.0.1 – – [08/May/2018 15:09:37] “POST /upload HTTP/1.1″ 200 –
    ImmutableMultiDict([(”, )])

    But in Postman the Body response is “No file found”

    Reply
    • May 8, 2018 at 6:42 pm
      Permalink

      Some characters are deleted, maybe this comment field doesn’t like the “greater-than” symbol.
      ImmutableMultiDict([(”, FileStorage: u’dropoffs.jpg’ (‘image/jpeg’))])

      Reply
  • February 15, 2019 at 12:13 am
    Permalink

    from flask import Flask, request, send_from_directory

    # set the “static” directory as the static folder.
    # this will ensure that all the static files are under one folder
    app = Flask(__name__, static_url_path=’/static’)

    # serving some static html files
    @app.route(‘/html/’)
    def send_html(path):
    return send_from_directory(‘static’, path)

    if __name__ == “__main__”:
    app.run()

    this code returns this error

    404 Not Found
    Not Found
    The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

    Reply

Leave a Reply

Advertisements
%d bloggers like this: