-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfastapi.py
More file actions
50 lines (38 loc) · 1.59 KB
/
fastapi.py
File metadata and controls
50 lines (38 loc) · 1.59 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
from collections.abc import Awaitable, Callable
from dataclasses import dataclass, field
from types import GenericAlias
from typing import Annotated, Any, TypeAlias, TypeAliasType
from fastapi import Depends
from injection import Module, mod
__all__ = ("Inject", "InjectThreadSafe")
@dataclass(eq=False, frozen=True, slots=True)
class FastAPIInject:
module: Module = field(default_factory=mod)
threadsafe: bool | None = field(default=None, kw_only=True)
def __call__[T](
self,
cls: type[T] | TypeAliasType | GenericAlias,
/,
default: T = NotImplemented,
*,
module: Module | None = None,
threadsafe: bool | None = None,
) -> Any:
module = module or self.module
threadsafe = self.threadsafe if threadsafe is None else threadsafe
awaitable = module.aget_lazy_instance(cls, default, threadsafe=threadsafe)
dependency = self.__make_dependency(awaitable)
dependency.__name__ = f"Inject[{getattr(cls, '__name__', str(cls))}]"
return Depends(dependency, use_cache=False)
def __getitem__[T, *Ts](self, params: T | tuple[T, *Ts], /) -> TypeAlias:
iter_params = iter(params if isinstance(params, tuple) else (params,))
cls = next(iter_params)
return Annotated[cls, self(cls), *iter_params]
@staticmethod
def __make_dependency[T](awaitable: Awaitable[T]) -> Callable[[], Awaitable[T]]:
async def dependency() -> T:
return await awaitable
return dependency
Inject = FastAPIInject()
InjectThreadSafe = FastAPIInject(threadsafe=True)
del FastAPIInject