Skip to main content

Static Assets and Resources

To configure static assets and access internal package resources, use the static_folder and static_url_path parameters during initialization and the open_resource method for file access.

from flask import Flask, current_app

# Initialize with a custom static folder and URL path
app = Flask(
__name__,
static_folder="assets",
static_url_path="/public"
)

# Access a non-static resource within the package
@app.route("/schema")
def get_schema():
with app.open_resource("schema.sql") as f:
content = f.read().decode("utf-8")
return content

Configuring Static Assets​

The Flask and Blueprint classes both inherit from Scaffold, which manages the location of static files. By default, Flask looks for a folder named static relative to the application's root_path.

  • static_folder: The directory containing your assets. It can be a relative path (to the app's root) or an absolute path. You can also use pathlib.Path objects.
  • static_url_path: The URL prefix used to serve these files. If not provided, it defaults to the name of the static_folder.

Using pathlib for Static Folders​

You can pass a pathlib.Path object to the static_folder argument:

from pathlib import Path
from flask import Flask

app = Flask(__name__, static_folder=Path("static_assets"))

Blueprint-Specific Static Assets​

Blueprints can maintain their own static folders, which is useful for modular applications:

from flask import Blueprint

admin_bp = Blueprint(
"admin",
__name__,
static_folder="admin_static",
static_url_path="/admin/static"
)

Accessing Internal Resources​

To read files that are part of your application package but are not intended to be served as static assets (like SQL schemas or configuration files), use open_resource.

Reading Package Data​

open_resource opens files relative to the application's root_path. It only supports reading ("r", "rt", or "rb").

# Example from examples/tutorial/flaskr/db.py
with current_app.open_resource("schema.sql") as f:
db.executescript(f.read().decode("utf8"))

You can also specify encoding for text mode:

# Using specific encoding in text mode
with app.open_resource("config.yaml", mode="rt", encoding="utf-8") as f:
config_data = f.read()

Accessing Instance Resources​

For files that need to be writable or are specific to a deployment instance (and thus not part of the version-controlled package), use open_instance_resource. These files are located in the instance_path.

# Instance resources can be opened for writing
with app.open_instance_resource("local_config.json", mode="w") as f:
f.write('{"debug": true}')

Troubleshooting​

Resource Write Errors​

The open_resource method is strictly for reading package data. If you attempt to open a file with a mode other than "r", "rt", or "rb", it will raise a ValueError.

  • Solution: Use open_instance_resource if you need to write to a file within the application's environment.

Static Route Not Found​

The automatic static route is only registered if has_static_folder is true. If you initialize Flask with static_folder=None, the /static endpoint will not exist.

  • Solution: Ensure static_folder is set to a valid string or path object during initialization.

Host Matching Requirements​

If you enable host_matching=True in the Flask constructor, you must also provide a static_host.

  • Solution:
    app = Flask(__name__, host_matching=True, static_host="static.example.com")
    Failure to provide static_host when host_matching is enabled will result in an AssertionError.