Skip to content
Open
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/dishka/integrations/litestar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
__all__ = [
"DishkaMiddleware",
"DishkaPlugin",
"FromDishka",
"LitestarProvider",
"inject",
Expand All @@ -12,7 +14,11 @@
from typing import ParamSpec, TypeVar, get_type_hints

from litestar import Controller, Litestar, Request, Router, WebSocket
from litestar.config.app import AppConfig
from litestar.enums import ScopeType
from litestar.middleware import ASGIMiddleware
from litestar.plugins import InitPlugin
from litestar.types import ASGIApp, Receive, Scope, Send
from litestar.handlers import (
BaseRouteHandler,
HTTPRouteHandler,
Expand Down Expand Up @@ -165,3 +171,46 @@ def setup_dishka(container: AsyncContainer, app: Litestar) -> None:
app.asgi_handler,
)
app.state.dishka_container = container


class DishkaMiddleware(ASGIMiddleware):
scopes = (ScopeType.HTTP, ScopeType.WEBSOCKET)
async def handle(
self, scope: Scope, receive: Receive,
send: Send, next_app: ASGIApp,
) -> None:
if scope.get("type") not in (ScopeType.HTTP, ScopeType.WEBSOCKET):
await next_app(scope, receive, send)
return

if scope.get("type") == ScopeType.HTTP:
request: Request = Request(scope)
r_context = {Request: request}
di_scope = DIScope.REQUEST
async with request.app.state.dishka_container(
r_context,
scope=di_scope,
) as request_container:
request.state.dishka_container = request_container
await next_app(scope, receive, send)

elif scope.get("type") == ScopeType.WEBSOCKET:
websocket: WebSocket = WebSocket(scope)
w_context = {WebSocket: websocket}
di_scope = DIScope.SESSION
async with websocket.app.state.dishka_container(
w_context,
scope=di_scope,
) as request_container:
websocket.state.dishka_container = request_container
await next_app(scope, receive, send)
Comment thread
euri10 marked this conversation as resolved.
Outdated


class DishkaPlugin(InitPlugin):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add plugin automatically inside setup_dishka?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think so,

the current api is

    app = litestar.Litestar()
    container = make_async_container(provider)
    setup_dishka(container, app)

and this PR just adds the possibility to do:

    container = make_async_container(provider)
    app = litestar.Litestar(plugins=[DishkaPlugin(container=container)])

I dont know a litestar's built-in way to add a plugin other than using the plugins kwarg unfortunately.

def __init__(self, container: AsyncContainer):
self.container = container

def on_app_init(self, app_config: AppConfig) -> AppConfig:
app_config.state.dishka_container = self.container
app_config.middleware.append(DishkaMiddleware())
return app_config