-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathscope.py
More file actions
71 lines (51 loc) · 1.85 KB
/
scope.py
File metadata and controls
71 lines (51 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import typing
import injector
import quart
import werkzeug.local
T = typing.TypeVar("T")
class RequestScope(injector.Scope):
"""
Request scope
A :class:`~injector.Scope` that returns a per-request instance for a key.
"""
def configure(self) -> None:
self._stack = werkzeug.local.LocalStack()
def push(self) -> None:
"""
Push new item onto stack.
"""
self._stack.push({})
def pop(self) -> None:
"""
Remove topmost item from stack.
"""
self._stack.pop()
def get(self, key: type[T], provider: injector.Provider[T]) -> injector.Provider[T]:
try:
return self._stack.top[key]
except KeyError:
provider = injector.InstanceProvider(provider.get(self.injector))
self._stack.top[key] = provider
return provider
request = injector.ScopeDecorator(RequestScope)
def bind_scope(
scope_cls: type[injector.Scope],
app: quart.Quart,
container: injector.Injector,
) -> None:
"""
Bind scope.
Bind the request scope class to applications before/teardown functions for requests
and websockets.
:param scope_cls: scope class to bind
:param app: quart application
:param container: dependency injection container
"""
async def before_func() -> None:
container.get(scope_cls).push()
async def teardown_func(_: BaseException | None) -> None:
container.get(scope_cls).pop()
app.before_request_funcs[None] = [(before_func, None)] + app.before_request_funcs[None]
app.before_websocket_funcs[None] = [(before_func, None)] + app.before_websocket_funcs[None]
app.teardown_request_funcs[None] = [(teardown_func, None)] + app.teardown_request_funcs[None]
app.teardown_websocket_funcs[None] = [(teardown_func, None)] + app.teardown_websocket_funcs[None]