789 lines
27 KiB
Python
789 lines
27 KiB
Python
from functools import update_wrapper
|
|
from json import JSONDecoder, JSONEncoder
|
|
from typing import Callable, Iterable, List, Optional, Type, TYPE_CHECKING, Union
|
|
|
|
from .static import PackageStatic
|
|
|
|
if TYPE_CHECKING:
|
|
from .app import Quart # noqa
|
|
|
|
DeferedSetupFunction = Callable[['BlueprintSetupState'], Callable]
|
|
|
|
|
|
class Blueprint(PackageStatic):
|
|
"""A blueprint is a collection of application properties.
|
|
|
|
The application properties include routes, error handlers, and
|
|
before and after request functions. It is useful to produce
|
|
modular code as it allows the properties to be defined in a
|
|
blueprint thereby defering the addition of these properties to the
|
|
app.
|
|
|
|
Attributes:
|
|
json_decoder: The decoder to use for routes in this blueprint,
|
|
the default, None, indicates that the app encoder should be
|
|
used.
|
|
json_encoder: The encoder to use for routes in this blueprint,
|
|
the default, None, indicates that the app encoder should be
|
|
used.
|
|
url_prefix: An additional prefix to every route rule in the
|
|
blueprint.
|
|
"""
|
|
|
|
json_decoder: Optional[JSONDecoder] = None
|
|
json_encoder: Optional[JSONEncoder] = None
|
|
|
|
def __init__(
|
|
self,
|
|
name: str,
|
|
import_name: str,
|
|
static_folder: Optional[str]=None,
|
|
static_url_path: Optional[str]=None,
|
|
template_folder: Optional[str]=None,
|
|
url_prefix: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
root_path: Optional[str]=None,
|
|
) -> None:
|
|
super().__init__(import_name, template_folder, root_path, static_folder, static_url_path)
|
|
self.name = name
|
|
self.url_prefix = url_prefix
|
|
self.deferred_functions: List[DeferedSetupFunction] = []
|
|
self.subdomain = subdomain
|
|
|
|
def route(
|
|
self,
|
|
path: str,
|
|
methods: Optional[List[str]]=None,
|
|
endpoint: Optional[str]=None,
|
|
defaults: Optional[dict]=None,
|
|
host: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
*,
|
|
provide_automatic_options: Optional[bool]=None,
|
|
strict_slashes: bool=True,
|
|
) -> Callable:
|
|
"""Add a route to the blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.route`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.route('/')
|
|
def route():
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.add_url_rule(
|
|
path, endpoint, func, methods, defaults=defaults, host=host, subdomain=subdomain,
|
|
provide_automatic_options=provide_automatic_options, strict_slashes=strict_slashes,
|
|
)
|
|
return func
|
|
return decorator
|
|
|
|
def add_url_rule(
|
|
self,
|
|
path: str,
|
|
endpoint: Optional[str]=None,
|
|
view_func: Optional[Callable]=None,
|
|
methods: Optional[Iterable[str]]=None,
|
|
defaults: Optional[dict]=None,
|
|
host: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
*,
|
|
provide_automatic_options: Optional[bool]=None,
|
|
is_websocket: bool=False,
|
|
strict_slashes: bool=True,
|
|
) -> None:
|
|
"""Add a route/url rule to the blueprint.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.add_url_rule`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def route():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.add_url_rule('/', route)
|
|
"""
|
|
endpoint = endpoint or view_func.__name__
|
|
if '.' in endpoint:
|
|
raise ValueError('Blueprint endpoints should not contain periods')
|
|
self.record(
|
|
lambda state: state.add_url_rule(
|
|
path, endpoint, view_func, methods, defaults, host, self.subdomain,
|
|
provide_automatic_options=provide_automatic_options, is_websocket=is_websocket,
|
|
strict_slashes=strict_slashes,
|
|
),
|
|
)
|
|
|
|
def websocket(
|
|
self,
|
|
path: str,
|
|
endpoint: Optional[str]=None,
|
|
defaults: Optional[dict]=None,
|
|
host: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
*,
|
|
strict_slashes: bool=True,
|
|
) -> Callable:
|
|
"""Add a websocket to the blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.websocket`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.websocket('/')
|
|
async def route():
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.add_websocket(
|
|
path, endpoint, func, defaults=defaults, host=host, subdomain=subdomain,
|
|
strict_slashes=strict_slashes,
|
|
)
|
|
return func
|
|
return decorator
|
|
|
|
def add_websocket(
|
|
self,
|
|
path: str,
|
|
endpoint: Optional[str]=None,
|
|
view_func: Optional[Callable]=None,
|
|
defaults: Optional[dict]=None,
|
|
host: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
*,
|
|
strict_slashes: bool=True,
|
|
) -> None:
|
|
"""Add a websocket rule to the blueprint.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.add_websocket`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def route():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.add_websocket('/', route)
|
|
"""
|
|
return self.add_url_rule(
|
|
path, endpoint, view_func, {'GET'}, defaults=defaults, host=host, subdomain=subdomain,
|
|
provide_automatic_options=False, is_websocket=True, strict_slashes=strict_slashes,
|
|
)
|
|
|
|
def endpoint(self, endpoint: str) -> Callable:
|
|
"""Add an endpoint to the blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.endpoint`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.endpoint('index')
|
|
def index():
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.record_once(lambda state: state.register_endpoint(endpoint, func))
|
|
return func
|
|
return decorator
|
|
|
|
def app_template_filter(self, name: Optional[str]=None) -> Callable:
|
|
"""Add an application wide template filter.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.template_filter`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_template_filter()
|
|
def filter(value):
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.add_app_template_filter(func, name=name)
|
|
return func
|
|
return decorator
|
|
|
|
def add_app_template_filter(self, func: Callable, name: Optional[str]=None) -> None:
|
|
"""Add an application wide template filter.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.add_template_filter`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def filter():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.add_app_template_filter(filter)
|
|
"""
|
|
self.record_once(lambda state: state.register_template_filter(func, name))
|
|
|
|
def app_template_test(self, name: Optional[str]=None) -> Callable:
|
|
"""Add an application wide template test.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.template_test`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_template_test()
|
|
def test(value):
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.add_app_template_test(func, name=name)
|
|
return func
|
|
return decorator
|
|
|
|
def add_app_template_test(self, func: Callable, name: Optional[str]=None) -> None:
|
|
"""Add an application wide template test.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.add_template_test`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def test():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.add_app_template_test(test)
|
|
"""
|
|
self.record_once(lambda state: state.register_template_test(func, name))
|
|
|
|
def app_template_global(self, name: Optional[str]=None) -> Callable:
|
|
"""Add an application wide template global.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.template_global`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_template_global()
|
|
def global(value):
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.add_app_template_global(func, name=name)
|
|
return func
|
|
return decorator
|
|
|
|
def add_app_template_global(self, func: Callable, name: Optional[str]=None) -> None:
|
|
"""Add an application wide template global.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.add_template_global`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def global():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.add_app_template_global(global)
|
|
"""
|
|
self.record_once(lambda state: state.register_template_global(func, name))
|
|
|
|
def before_request(self, func: Callable) -> Callable:
|
|
"""Add a before request function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.before_request`. It applies only to requests that
|
|
are routed to an endpoint in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.before_request
|
|
def before():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.before_request(func, self.name))
|
|
return func
|
|
|
|
def before_websocket(self, func: Callable) -> Callable:
|
|
"""Add a before request websocket to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.before_websocket`. It applies only to requests that
|
|
are routed to an endpoint in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.before_websocket
|
|
def before():
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.before_websocket(func, self.name))
|
|
return func
|
|
|
|
def before_app_request(self, func: Callable) -> Callable:
|
|
"""Add a before request function to the app.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.before_request`. It applies to all requests to the
|
|
app this blueprint is registered on. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.before_app_request
|
|
def before():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.before_request(func))
|
|
return func
|
|
|
|
def before_app_websocket(self, func: Callable) -> Callable:
|
|
"""Add a before request websocket to the App.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.before_websocket`. It applies to all requests to the
|
|
app this blueprint is registered on. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.before_app_websocket
|
|
def before():
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.before_websocket(func))
|
|
return func
|
|
|
|
def before_app_first_request(self, func: Callable) -> Callable:
|
|
"""Add a before request first function to the app.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.before_first_request`. It is
|
|
triggered before the first request to the app this blueprint
|
|
is registered on. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.before_app_first_request
|
|
def before_first():
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.before_first_request(func))
|
|
return func
|
|
|
|
def after_request(self, func: Callable) -> Callable:
|
|
"""Add an after request function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.after_request`. It applies only to requests that
|
|
are routed to an endpoint in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.after_request
|
|
def after():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.after_request(func, self.name))
|
|
return func
|
|
|
|
def after_websocket(self, func: Callable) -> Callable:
|
|
"""Add an after websocket function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.after_websocket`. It applies only to requests that
|
|
are routed to an endpoint in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.after_websocket
|
|
def after():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.after_websocket(func, self.name))
|
|
return func
|
|
|
|
def after_app_request(self, func: Callable) -> Callable:
|
|
"""Add a after request function to the app.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.after_request`. It applies to all requests to the
|
|
app this blueprint is registered on. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.after_app_request
|
|
def after():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.after_request(func))
|
|
return func
|
|
|
|
def after_app_websocket(self, func: Callable) -> Callable:
|
|
"""Add an after websocket function to the App.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.after_websocket`. It applies to all requests to the
|
|
ppe this blueprint is registerd on. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.after_app_websocket
|
|
def after():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.after_websocket(func))
|
|
return func
|
|
|
|
def teardown_request(self, func: Callable) -> Callable:
|
|
"""Add a teardown request function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same arguments
|
|
as :meth:`~quart.Quart.teardown_request`. It applies only to requests that
|
|
are routed to an endpoint in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.teardown_request
|
|
def teardown():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.teardown_request(func, self.name))
|
|
return func
|
|
|
|
def teardown_websocket(self, func: Callable) -> Callable:
|
|
"""Add a teardown websocket function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.teardown_websocket`. It
|
|
applies only to requests that are routed to an endpoint in
|
|
this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.teardown_websocket
|
|
def teardown():
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.teardown_websocket(func, self.name))
|
|
return func
|
|
|
|
def teardown_app_request(self, func: Callable) -> Callable:
|
|
"""Add a teardown request function to the app.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.teardown_request`. It applies
|
|
to all requests to the app this blueprint is registered on. An
|
|
example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.teardown_app_request
|
|
def teardown():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.teardown_request(func))
|
|
return func
|
|
|
|
def errorhandler(self, error: Union[Type[Exception], int]) -> Callable:
|
|
"""Add an error handler function to the Blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.errorhandler`. It applies
|
|
only to errors that originate in routes in this blueprint. An
|
|
example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.errorhandler(404)
|
|
def not_found():
|
|
...
|
|
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.register_error_handler(error, func)
|
|
return func
|
|
return decorator
|
|
|
|
def app_errorhandler(self, error: Union[Type[Exception], int]) -> Callable:
|
|
"""Add an error handler function to the App.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.errorhandler`. It applies
|
|
only to all errors. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_errorhandler(404)
|
|
def not_found():
|
|
...
|
|
"""
|
|
def decorator(func: Callable) -> Callable:
|
|
self.record_once(lambda state: state.app.register_error_handler(error, func))
|
|
return func
|
|
return decorator
|
|
|
|
def register_error_handler(self, error: Union[Type[Exception], int], func: Callable) -> None:
|
|
"""Add an error handler function to the blueprint.
|
|
|
|
This is designed to be used on the blueprint directly, and
|
|
has the same arguments as
|
|
:meth:`~quart.Quart.register_error_handler`. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
def not_found():
|
|
...
|
|
|
|
blueprint = Blueprint(__name__)
|
|
blueprint.register_error_handler(404, not_found)
|
|
"""
|
|
self.record_once(lambda state: state.app.register_error_handler(error, func, self.name))
|
|
|
|
def context_processor(self, func: Callable) -> Callable:
|
|
"""Add a context processor function to this blueprint.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.context_processor`. This will
|
|
add context to all templates rendered in this blueprint's
|
|
routes. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.context_processor
|
|
def processor():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.context_processor(func, self.name))
|
|
return func
|
|
|
|
def app_context_processor(self, func: Callable) -> Callable:
|
|
"""Add a context processor function to the app.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.context_processor`. This will
|
|
add context to all templates rendered. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_context_processor
|
|
def processor():
|
|
...
|
|
"""
|
|
self.record_once(lambda state: state.app.context_processor(func))
|
|
return func
|
|
|
|
def url_value_preprocessor(self, func: Callable) -> Callable:
|
|
"""Add a url value preprocessor.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.url_value_preprocessor`. This
|
|
will apply to urls in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.url_value_preprocessor
|
|
def processor(endpoint, view_args):
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.url_value_preprocessor(func, self.name))
|
|
return func
|
|
|
|
def app_url_value_preprocessor(self, func: Callable) -> Callable:
|
|
"""Add a url value preprocessor.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as
|
|
:meth:`~quart.Quart.app_url_value_preprocessor`. This will
|
|
apply to all URLs. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_url_value_preprocessor
|
|
def processor(endpoint, view_args):
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.url_value_preprocessor(func))
|
|
return func
|
|
|
|
def url_defaults(self, func: Callable) -> Callable:
|
|
"""Add a url default preprocessor.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.url_defaults`. This will
|
|
apply to urls in this blueprint. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.url_defaults
|
|
def default(endpoint, values):
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.url_defaults(func, self.name))
|
|
return func
|
|
|
|
def app_url_defaults(self, func: Callable) -> Callable:
|
|
"""Add a url default preprocessor.
|
|
|
|
This is designed to be used as a decorator, and has the same
|
|
arguments as :meth:`~quart.Quart.url_defaults`. This will
|
|
apply to all urls. An example usage,
|
|
|
|
.. code-block:: python
|
|
|
|
blueprint = Blueprint(__name__)
|
|
@blueprint.app_url_defaults
|
|
def default(endpoint, values):
|
|
...
|
|
|
|
"""
|
|
self.record_once(lambda state: state.app.url_defaults(func))
|
|
return func
|
|
|
|
def record(self, func: DeferedSetupFunction) -> None:
|
|
"""Used to register a deferred action."""
|
|
self.deferred_functions.append(func)
|
|
|
|
def record_once(self, func: DeferedSetupFunction) -> None:
|
|
"""Used to register a deferred action that happens only once."""
|
|
def wrapper(state: 'BlueprintSetupState') -> None:
|
|
if state.first_registration:
|
|
func(state)
|
|
self.record(update_wrapper(wrapper, func))
|
|
|
|
def register(
|
|
self,
|
|
app: 'Quart',
|
|
first_registration: bool,
|
|
*,
|
|
url_prefix: Optional[str]=None,
|
|
) -> None:
|
|
"""Register this blueprint on the app given."""
|
|
state = self.make_setup_state(app, first_registration, url_prefix=url_prefix)
|
|
|
|
if self.has_static_folder:
|
|
state.add_url_rule(
|
|
self.static_url_path + '/<path:filename>',
|
|
view_func=self.send_static_file, endpoint='static',
|
|
)
|
|
|
|
for func in self.deferred_functions:
|
|
func(state)
|
|
|
|
def make_setup_state(
|
|
self,
|
|
app: 'Quart',
|
|
first_registration: bool,
|
|
*,
|
|
url_prefix: Optional[str]=None,
|
|
) -> 'BlueprintSetupState':
|
|
"""Return a blueprint setup state instance.
|
|
|
|
Arguments:
|
|
first_registration: True if this is the first registration
|
|
of this blueprint on the app.
|
|
url_prefix: An optional prefix to all rules
|
|
"""
|
|
return BlueprintSetupState(self, app, first_registration, url_prefix=url_prefix)
|
|
|
|
|
|
class BlueprintSetupState:
|
|
"""This setups the blueprint on the app.
|
|
|
|
When used it can apply the deferred functions on the Blueprint to
|
|
the app. Override if you wish for blueprints to have be registered
|
|
in different ways.
|
|
|
|
Attributes:
|
|
first_registration: True if this is the first registration
|
|
of this blueprint on the app.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
blueprint: Blueprint,
|
|
app: 'Quart',
|
|
first_registration: bool,
|
|
*,
|
|
url_prefix: Optional[str]=None,
|
|
) -> None:
|
|
self.blueprint = blueprint
|
|
self.app = app
|
|
self.url_prefix = url_prefix or self.blueprint.url_prefix
|
|
self.first_registration = first_registration
|
|
|
|
def add_url_rule(
|
|
self,
|
|
path: str,
|
|
endpoint: Optional[str]=None,
|
|
view_func: Optional[Callable]=None,
|
|
methods: Optional[Iterable[str]]=None,
|
|
defaults: Optional[dict]=None,
|
|
host: Optional[str]=None,
|
|
subdomain: Optional[str]=None,
|
|
*,
|
|
provide_automatic_options: Optional[bool]=None,
|
|
is_websocket: bool=False,
|
|
strict_slashes: bool=True,
|
|
) -> None:
|
|
if self.url_prefix is not None:
|
|
path = f"{self.url_prefix}{path}"
|
|
endpoint = f"{self.blueprint.name}.{endpoint}"
|
|
self.app.add_url_rule(
|
|
path, endpoint, view_func, methods, defaults, host=host, subdomain=subdomain,
|
|
provide_automatic_options=provide_automatic_options, is_websocket=is_websocket,
|
|
strict_slashes=strict_slashes,
|
|
)
|
|
|
|
def register_endpoint(self, endpoint: str, func: Callable) -> None:
|
|
self.app.view_functions[endpoint] = func
|
|
|
|
def register_template_filter(self, func: Callable, name: Optional[str]) -> None:
|
|
self.app.add_template_filter(func, name)
|
|
|
|
def register_template_test(self, func: Callable, name: Optional[str]) -> None:
|
|
self.app.add_template_test(func, name)
|
|
|
|
def register_template_global(self, func: Callable, name: Optional[str]) -> None:
|
|
self.app.add_template_global(func, name)
|