Source code for picobox.ext.flaskscopes
"""Scopes for Flask framework."""
import uuid
import flask
import picobox
class _flaskscope(picobox.Scope):
"""A base class for Flask scopes."""
_store = None
def __init__(self):
# Both application and request scopes are merely proxies to
# corresponding storage objects in Flask. This means multiple
# scope instances will share the same storage object under the
# hood, and this is not what we want. So we need to generate
# some unique key per scope instance and use that key to
# distinguish dependencies stored by different scope instances.
self._uuid = str(uuid.uuid4())
def set(self, key, value):
try:
dependencies = self._store.__dependencies__
except AttributeError:
dependencies = self._store.__dependencies__ = {}
try:
dependencies = dependencies[self._uuid]
except KeyError:
dependencies = dependencies.setdefault(self._uuid, {})
dependencies[key] = value
def get(self, key):
try:
rv = self._store.__dependencies__[self._uuid][key]
except (AttributeError, KeyError):
raise KeyError(key)
return rv
[docs]
class application(_flaskscope):
"""Share instances across the same Flask (HTTP) application.
In typical scenarios, a single Flask application exists, making this scope
interchangeable with :class:`picobox.singleton`. However, unlike the
latter, the application scope ensures that dependencies are bound to the
lifespan of a specific application instance. This is particularly useful in
testing scenarios where each test involves creating a new application
instance or in situations where you have `multiple Flask applications`__.
.. __: https://flask.palletsprojects.com/en/3.0.x/patterns/appdispatch/
Unlike :class:`picobox.ext.wsgiscopes.application`, it requires no WSGI
middlewares.
.. versionadded:: 2.2
"""
@property
def _store(self):
return flask.current_app
[docs]
class request(_flaskscope):
"""Share instances across the same Flask (HTTP) request.
You might want to store your SQLAlchemy session or Request-ID per request.
In many cases this produces much more readable code than passing the whole
request context around.
Unlike :class:`picobox.ext.wsgiscopes.request`, it requires no WSGI
middlewares.
.. versionadded:: 2.2
"""
@property
def _store(self):
return flask.g