Classes as Dependencies
"Callable", remember?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | class MyClass: pass
MyClass() # It is a "call"! 1-st call
class MyClass:
def __call__(): pass
m = MyClass()
m() # It is a "call" too! 2-nd call
class MyClass:
@classmethod
def f(): pass
MyClass.f() # Yet another "call"! 3-rd call
class MyClass
def f(self): pass
MyClass().f() # "call"? 4-th call
|
Yep, all of these examples can be used as a dependency!
INIT (1-st call)
You can use class initializer as a dependency. This way, object of this class will be the type of your dependency:
1
2
3
4
5
6
7
8
9
10
11
12 | from typing import Any
from fast_depends import inject, Depends
class MyDependency:
def __init__(self, a: int):
self.field = a
@inject
def func(d: Any = Depends(MyDependency)):
return d.field
assert func(a=3) == 3
|
Warning
You should use Any
annotation if MyDependency
is not a pydantic.BaseModel
subclass. Using MyDependency
annotation raises ValueError
exception at code inicialization time as the pydantic can't cast any value to not-pydantic class.
CALL (2-nd call)
If you wish to specify your dependency behavior earlier, you can use __call__
method of already initialized class object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | from fast_depends import inject, Depends
class MyDependency:
def __init__(self, a: int):
self.field = a
def __call__(self, b: int):
return self.field + b
@inject
def func(d: int = Depends(MyDependency(3))):
return d
assert func(b=3) == 6
|
CLASSMETHOD or STATICMETHOD (3-rd call)
Also, you can use classmethods or staticmethod as dependencies. It can be helpful with some OOP patterns (Strategy as an example).
1
2
3
4
5
6
7
8
9
10
11
12 | from fast_depends import inject, Depends
class MyDependency:
@staticmethod
def dep(a: int):
return a ** 2
@inject
def func(d: int = Depends(MyDependency.dep)):
return d
assert func(a=3) == 9
|
ANY METHOD (4-th call)
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | from fast_depends import inject, Depends
class MyDependency:
def __init__(self, a):
self.field = a
def dep(self, a: int):
return self.field + a
@inject
def func(d: int = Depends(MyDependency(3).dep)):
return d
assert func(a=3) == 6
|
Async
Only 3-rd and 4-th call methods are able to be async
type