123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- 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)
|