Skip to content

Instantly share code, notes, and snippets.

@Lancetnik
Created April 23, 2024 15:41
Show Gist options
  • Save Lancetnik/c35601f4db4606b0bf2eed32e11c4a52 to your computer and use it in GitHub Desktop.
Save Lancetnik/c35601f4db4606b0bf2eed32e11c4a52 to your computer and use it in GitHub Desktop.
from typing import Sequence
from functools import wraps
from dishka.container import Container
from dishka.integrations.base import wrap_injection
from django.urls import URLPattern
CONTAINER_NAME = "dishka_container"
def inject(func):
wrapped_func = wrap_injection(
func=func,
remove_depends=True,
container_getter=lambda _, p: p.pop(CONTAINER_NAME),
additional_params=(),
is_async=False,
)
@wraps(wrapped_func)
def wrapper(*args, **kwargs):
container: Container = kwargs[CONTAINER_NAME]
with container() as request_scope:
return wrapped_func(
*args,
**{
**kwargs,
CONTAINER_NAME: request_scope,
},
)
return wrapper
def setup_dishka(
urlpatterns: Sequence[URLPattern],
container: Container,
*,
auto_inject: bool = False,
) -> Sequence[URLPattern]:
for pattern in urlpatterns:
pattern.default_args = {
**(pattern.default_args or {}),
CONTAINER_NAME: container,
}
if auto_inject:
pattern.callback = inject(pattern.callback)
return urlpatterns
from django.urls import path
from .views import get
urlpatterns = [
path("test/", get),
]
from dishka import make_container, Provider, provide, Scope
class MyProvider(Provider):
@provide(scope=Scope.APP)
def get_int(self) -> int:
return 3
@provide(scope=Scope.REQUEST)
def get_float(self) -> float:
return 3.0
from .integration import setup_dishka
setup_dishka(
urlpatterns,
make_container(MyProvider(),),
auto_inject=True,
)
from django.http import JsonResponse, HttpRequest
from dishka import FromDishka
def get(
request: HttpRequest,
a: FromDishka[int],
b: FromDishka[float],
) -> JsonResponse:
print(b, a)
return JsonResponse({})
@Dark04072006
Copy link

интересно, а как с class-based вьюхами использовать? Написать какой-нибудь DishkaViewMixin?

@Lancetnik
Copy link
Author

Вообще, он и сейчас будет работать, но нужно тестить

@Dark04072006
Copy link

у меня все работает, но я понятия не имею как тесты написать, чтобы они были такими же гибкими, как в тестах других интеграций :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment