Redefining root and template dir in flask [duplicate]
In production, configure the HTTP server (Nginx, Apache, etc.) in front of your application to serve requests to /static
from the static folder. A dedicated web server is very good at serving static files efficiently, although you probably won't notice a difference compared to Flask at low volumes.
Flask automatically creates a /static/<path:filename>
route that will serve any filename
under the static
folder next to the Python module that defines your Flask app. Use url_for
to link to static files: url_for('static', filename='js/analytics.js')
You can also use send_from_directory
to serve files from a directory in your own route. This takes a base directory and a path, and ensures that the path is contained in the directory, which makes it safe to accept user-provided paths. This can be useful in cases where you want to check something before serving the file, such as if the logged in user has permission.
from flask import send_from_directory
@app.route('/reports/<path:path>')
def send_report(path):
return send_from_directory('reports', path)
Do not use send_file
or send_static_file
with a user-supplied path. send_from_directory
was designed to safely handle user-supplied paths under a known directory, and will raise an error if the path attempts to escape the directory.
If you are generating a file in memory without writing it to the filesystem, you can pass a BytesIO
object to send_file
to serve it like a file. You'll need to pass other arguments to send_file
in this case since it can't infer things like the file name or content type.
If you just want to move the location of your static files, then the simplest method is to declare the paths in the constructor. In the example below, I have moved my templates and static files into a sub-folder called web
.
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
-
static_url_path=''
removes any preceding path from the URL (i.e. the default/static
). -
static_folder='web/static'
to serve any files found in the folderweb/static
as static files. -
template_folder='web/templates'
similarly, this changes the templates folder.
Using this method, the following URL will return a CSS file:
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
And finally, here's a snap of the folder structure, where flask_server.py
is the Flask instance:
You can also, and this is my favorite, set a folder as static path so that the files inside are reachable for everyone.
app = Flask(__name__, static_url_path='/static')
With that set you can use the standard HTML:
<link rel="stylesheet" type="text/css" href="/static/style.css">