Skip to content

Commit 9477d8e

Browse files
committed
Dropped global guard as provider, added GLOBAL_GUARDS and GLOBAL_INTERCEPTORS to config and exposed application utility functions
1 parent 2022260 commit 9477d8e

File tree

19 files changed

+310
-183
lines changed

19 files changed

+310
-183
lines changed

ellar/app/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1+
from .context import (
2+
enable_versioning,
3+
use_authentication_schemes,
4+
use_exception_handler,
5+
use_global_guards,
6+
use_global_interceptors,
7+
)
18
from .factory import AppFactory
29
from .main import App
310

411
__all__ = [
512
"App",
613
"AppFactory",
14+
"use_exception_handler",
15+
"use_global_guards",
16+
"use_global_interceptors",
17+
"use_authentication_schemes",
18+
"enable_versioning",
719
]

ellar/app/context.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import typing as t
2+
3+
from ellar.auth.handlers import AuthenticationHandlerType
4+
from ellar.common import (
5+
EllarInterceptor,
6+
GuardCanActivate,
7+
IExceptionHandler,
8+
IIdentitySchemes,
9+
)
10+
from ellar.core import VersioningSchemes, current_config, current_injector
11+
from ellar.di import is_decorated_with_injectable
12+
from ellar.di.injector.tree_manager import TreeData
13+
from ellar.events import ensure_build_context
14+
15+
16+
@ensure_build_context(app_ready=True)
17+
def ensure_available_in_providers(*items: t.Any) -> None:
18+
"""
19+
Ensures that Providers at least belows to a particular module
20+
:param items:
21+
:return:
22+
"""
23+
app_module = current_injector.tree_manager.get_app_module()
24+
25+
def _predicate(item_: t.Type) -> t.Callable:
26+
def _(data: TreeData) -> bool:
27+
return item_ in data.exports or item_ in data.providers
28+
29+
return _
30+
31+
for item in items:
32+
if isinstance(item, type) and is_decorated_with_injectable(item):
33+
module = next(
34+
app_module.tree_manager.find_module(predicate=_predicate(item))
35+
)
36+
if not module:
37+
# if no module was found, we add item to ApplicationModule and export it also
38+
app_module.tree_manager.get_app_module().add_provider(
39+
provider=item, export=True
40+
)
41+
42+
43+
@ensure_build_context(app_ready=True)
44+
def use_authentication_schemes(*authentication: AuthenticationHandlerType) -> None:
45+
"""
46+
Registered Authentication Handlers to the application
47+
:param authentication:
48+
:return:
49+
"""
50+
__identity_scheme = current_injector.get(IIdentitySchemes)
51+
for auth in authentication:
52+
__identity_scheme.add_authentication(auth)
53+
ensure_available_in_providers(auth)
54+
55+
56+
@ensure_build_context()
57+
def use_exception_handler(
58+
*exception_handlers: IExceptionHandler,
59+
) -> None:
60+
"""
61+
Adds Application Exception Handlers
62+
:param exception_handlers: IExceptionHandler
63+
:return:
64+
"""
65+
for exception_handler in exception_handlers:
66+
if exception_handler not in current_config.EXCEPTION_HANDLERS:
67+
current_config.EXCEPTION_HANDLERS = current_config.EXCEPTION_HANDLERS + [
68+
exception_handler
69+
]
70+
ensure_available_in_providers(exception_handler)
71+
72+
73+
@ensure_build_context()
74+
def enable_versioning(
75+
schema: VersioningSchemes,
76+
version_parameter: str = "version",
77+
default_version: t.Optional[str] = None,
78+
**init_kwargs: t.Any,
79+
) -> None:
80+
"""
81+
Enables an Application Versioning scheme
82+
:param schema: VersioningSchemes
83+
:param version_parameter: versioning parameter lookup key. Default: 'version'
84+
:param default_version: versioning default value. Default: None
85+
:param init_kwargs: Other schema initialization keyword args.
86+
:return:
87+
"""
88+
current_config.VERSIONING_SCHEME = schema.value(
89+
version_parameter=version_parameter,
90+
default_version=default_version,
91+
**init_kwargs,
92+
)
93+
94+
95+
@ensure_build_context(app_ready=True)
96+
def use_global_guards(
97+
*guards: t.Union[GuardCanActivate, t.Type[GuardCanActivate]],
98+
) -> None:
99+
"""
100+
Registers Application Global Guards that affects all routes registered in ApplicationRouter
101+
:param guards:
102+
:return: None
103+
"""
104+
current_config.GLOBAL_GUARDS = list(current_config.GLOBAL_GUARDS) + list(guards)
105+
ensure_available_in_providers(*guards)
106+
107+
108+
@ensure_build_context(app_ready=True)
109+
def use_global_interceptors(
110+
*interceptors: t.Union[EllarInterceptor, t.Type[EllarInterceptor]],
111+
) -> None:
112+
"""
113+
Registers Application Global Interceptor that affects all routes registered in ApplicationRouter
114+
:param interceptors:
115+
:return: None
116+
"""
117+
current_config.GLOBAL_INTERCEPTORS = list(
118+
current_config.GLOBAL_INTERCEPTORS
119+
) + list(interceptors)
120+
ensure_available_in_providers(*interceptors)

ellar/app/factory.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ellar.di.injector.tree_manager import ModuleTreeManager
2222
from ellar.reflect import reflect
2323
from ellar.threading.sync_worker import execute_async_context_manager, execute_coroutine
24-
from ellar.utils import get_name, get_unique_type
24+
from ellar.utils import get_unique_type
2525
from starlette.routing import Host, Mount
2626

2727
from ..events.build import build_with_context_event
@@ -108,6 +108,7 @@ def _get_config_kwargs() -> t.Dict:
108108
return dict(config_module)
109109

110110
config = Config(app_configured=True, **_get_config_kwargs())
111+
config.GLOBAL_GUARDS += list(global_guards or [])
111112

112113
# injector = EllarInjector(auto_bind=config.INJECTOR_AUTO_BIND, parent=injector)
113114
# injector.container.register_instance(config, concrete_type=Config)
@@ -137,11 +138,10 @@ def _get_config_kwargs() -> t.Dict:
137138
config=config,
138139
injector=app_module_ref.container.injector,
139140
lifespan=config.DEFAULT_LIFESPAN_HANDLER,
140-
global_guards=global_guards,
141141
)
142142
# tag application instance by ApplicationModule name
143143
core_module_ref.add_provider(
144-
ProviderConfig(App, use_value=app, tag=get_name(module), export=True)
144+
ProviderConfig(App, use_value=app, tag="App", export=True)
145145
)
146146
app_module_ref.build_dependencies()
147147

0 commit comments

Comments
 (0)