Resource and Static File Management
In this framework, resource management is centered around the concept of a root path, which serves as the anchor for locating static files, templates, and internal application data. This functionality is primarily implemented in the Scaffold base class and specialized within the Flask application object.
The Root Path and Resource Discovery
Every application and blueprint is a Scaffold instance. When you initialize Flask(__name__), the import_name (usually __name__) is used to automatically detect the root_path. This path is the absolute filesystem path to the package or module.
The root_path is critical because all other resource paths—static files, templates, and custom resources—are resolved relative to it. If automatic detection fails (for example, with namespace packages), you can provide it explicitly during initialization.
# src/flask/sansio/scaffold.py
if root_path is None:
root_path = get_root_path(self.import_name)
self.root_path = root_path
Static File Configuration
Static files are served from a designated directory, which defaults to a folder named static inside your application's root path.
Configuration Properties
The Scaffold class manages two primary properties for static files:
static_folder: The absolute path to the directory containing static files.static_url_path: The URL prefix used to access these files (e.g.,/static).
If static_url_path is not provided, it defaults to the basename of the static_folder.
Automatic Route Registration
When a Flask application is initialized with a static_folder, it automatically registers a route to serve these files using the send_static_file method.
# src/flask/app.py
if self.has_static_folder:
self.add_url_rule(
f"{self.static_url_path}/<path:filename>",
endpoint="static",
host=static_host,
view_func=lambda **kw: self_ref().send_static_file(**kw),
)
The send_static_file method uses send_from_directory to safely deliver files and integrates with the application's configuration to determine cache headers via get_send_file_max_age.
Template Folder Management
The template_folder configuration determines where the application looks for Jinja2 templates. By default, this is a folder named templates relative to the root_path.
The Scaffold class provides a jinja_loader property that creates a jinja2.loaders.FileSystemLoader pointing to this directory. This loader is then used by the Flask application when creating the Jinja environment.
# src/flask/sansio/scaffold.py
@cached_property
def jinja_loader(self) -> BaseLoader | None:
if self.template_folder is not None:
return FileSystemLoader(os.path.join(self.root_path, self.template_folder))
return None
Accessing Internal Resources
The framework provides two primary methods for reading files bundled with the application or stored in the instance folder.
Application Resources
The open_resource method is used to open files relative to the application's root_path. This is commonly used for reading configuration schemas or initial data files. Note that this method only supports reading ("r", "rt", or "rb").
A typical use case is found in the database initialization of the flaskr tutorial:
# examples/tutorial/flaskr/db.py
with current_app.open_resource("schema.sql") as f:
db.executescript(f.read().decode("utf8"))
Instance Resources
For files that need to be written to at runtime or should not be part of the version-controlled package (like SQLite databases or secret keys), the open_instance_resource method is used. This resolves paths relative to the instance_path, which is typically a folder named instance located next to the application package.
Unlike open_resource, open_instance_resource allows opening files for writing.
# src/flask/app.py
def open_instance_resource(self, resource, mode="rb", encoding="utf-8"):
path = os.path.join(self.instance_path, resource)
if "b" in mode:
return open(path, mode)
return open(path, mode, encoding=encoding)
Resource Isolation in Blueprints
Because Blueprint also inherits from Scaffold, it can maintain its own independent static_folder and template_folder. This allows modular components to carry their own assets. When a blueprint is registered, its resources are integrated into the application, but they remain physically located within the blueprint's own root_path.