How to serve static files with Python 3 + Flask
Python Flask is a good microframework for building a minimal viable product to validate our ideas on the Internet. A modern web application encompasses documents that tell the web browser how to build the visuals of our web application and communicate with our server backend. Such documents are usually static in nature and are served as they are to the web browser without any processing from the server end.
Comparing setting up an instance of the Nginx server with adding code in our Flask application, the latter can be a more convenient way for us to realise our minimal viable product. This post documents the proof of concept that I did to serve static files with Python 3 and Flask.
Sample code to serve static files with Python 3 + Flask
The following is the code that I wrote to serve static files that are contained in a directory that is named as "static":
import os from flask import Flask from flask import send_from_directory static_file_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static') app = Flask(__name__) @app.route('/dir', methods=['GET']) def serve_dir_directory_index(): return send_from_directory(static_file_dir, 'index.html') @app.route('/dir/<path:path>', methods=['GET']) def serve_file_in_dir(path): if not os.path.isfile(os.path.join(static_file_dir, path)): path = os.path.join(path, 'index.html') return send_from_directory(static_file_dir, path) app.run(host='0.0.0.0',port=8080)
For this code to work, I had placed it in the same directory level as the directory that is named as "static". The first 3 statements imported the
os module, the
flask.Flask class and
flask.send_from_directory function from flask.
To get the directory that contains the static files, I first get the directory path of the Python file that contains this code by calling
os.path.dirname(os.path.realpath(__file__)). I then call
os.path.join to construct the path to the directory that contains the static files and store it in the
I then create an instance of the Flask class for realising the web server and made it available via the
app variable. With the app variable, I then decorated the
serve_dir_directory_index function and the
serve_file_in_dir function with app.route. That would cause Flask to direct HTTP GET requests for
serve_dir_directory_index and HTTP GET requests for
serve_dir_directory_index, I call
send_from_directory to attempt to return a
index.html that resides in the root level of
static_file_dir. This would emulate the behaviour of returning a Webserver directory index for
serve_file_in_dir, I first check whether the requested uri corresponds to an actual file. If not, it would mean that the HTTP GET request is directed at a directory within
/dir. For such a case, I changed the path to point to a
index.html that is located at the root level of that directory. Finally, I used
send_from_directory to attempt to return the corresponding file back to the web browser.
The last statement,
app.run(host='0.0.0.0',port=8080), starts the web server that listens on port 8080 for incoming HTTP requests.