Spaces:
Running
Running
from __future__ import annotations | |
import os | |
import typing as t | |
from datetime import timedelta | |
from .cli import AppGroup | |
from .globals import current_app | |
from .helpers import send_from_directory | |
from .sansio.blueprints import Blueprint as SansioBlueprint | |
from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa | |
from .sansio.scaffold import _sentinel | |
if t.TYPE_CHECKING: # pragma: no cover | |
from .wrappers import Response | |
class Blueprint(SansioBlueprint): | |
def __init__( | |
self, | |
name: str, | |
import_name: str, | |
static_folder: str | os.PathLike[str] | None = None, | |
static_url_path: str | None = None, | |
template_folder: str | os.PathLike[str] | None = None, | |
url_prefix: str | None = None, | |
subdomain: str | None = None, | |
url_defaults: dict[str, t.Any] | None = None, | |
root_path: str | None = None, | |
cli_group: str | None = _sentinel, # type: ignore | |
) -> None: | |
super().__init__( | |
name, | |
import_name, | |
static_folder, | |
static_url_path, | |
template_folder, | |
url_prefix, | |
subdomain, | |
url_defaults, | |
root_path, | |
cli_group, | |
) | |
#: The Click command group for registering CLI commands for this | |
#: object. The commands are available from the ``flask`` command | |
#: once the application has been discovered and blueprints have | |
#: been registered. | |
self.cli = AppGroup() | |
# Set the name of the Click group in case someone wants to add | |
# the app's commands to another CLI tool. | |
self.cli.name = self.name | |
def get_send_file_max_age(self, filename: str | None) -> int | None: | |
"""Used by :func:`send_file` to determine the ``max_age`` cache | |
value for a given file path if it wasn't passed. | |
By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from | |
the configuration of :data:`~flask.current_app`. This defaults | |
to ``None``, which tells the browser to use conditional requests | |
instead of a timed cache, which is usually preferable. | |
Note this is a duplicate of the same method in the Flask | |
class. | |
.. versionchanged:: 2.0 | |
The default configuration is ``None`` instead of 12 hours. | |
.. versionadded:: 0.9 | |
""" | |
value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] | |
if value is None: | |
return None | |
if isinstance(value, timedelta): | |
return int(value.total_seconds()) | |
return value # type: ignore[no-any-return] | |
def send_static_file(self, filename: str) -> Response: | |
"""The view function used to serve files from | |
:attr:`static_folder`. A route is automatically registered for | |
this view at :attr:`static_url_path` if :attr:`static_folder` is | |
set. | |
Note this is a duplicate of the same method in the Flask | |
class. | |
.. versionadded:: 0.5 | |
""" | |
if not self.has_static_folder: | |
raise RuntimeError("'static_folder' must be set to serve static_files.") | |
# send_file only knows to call get_send_file_max_age on the app, | |
# call it here so it works for blueprints too. | |
max_age = self.get_send_file_max_age(filename) | |
return send_from_directory( | |
t.cast(str, self.static_folder), filename, max_age=max_age | |
) | |
def open_resource( | |
self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" | |
) -> t.IO[t.AnyStr]: | |
"""Open a resource file relative to :attr:`root_path` for reading. The | |
blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource` | |
method. | |
:param resource: Path to the resource relative to :attr:`root_path`. | |
:param mode: Open the file in this mode. Only reading is supported, | |
valid values are ``"r"`` (or ``"rt"``) and ``"rb"``. | |
:param encoding: Open the file with this encoding when opening in text | |
mode. This is ignored when opening in binary mode. | |
.. versionchanged:: 3.1 | |
Added the ``encoding`` parameter. | |
""" | |
if mode not in {"r", "rt", "rb"}: | |
raise ValueError("Resources can only be opened for reading.") | |
path = os.path.join(self.root_path, resource) | |
if mode == "rb": | |
return open(path, mode) # pyright: ignore | |
return open(path, mode, encoding=encoding) | |