authentik.root.asgi
ASGI config for authentik project.
It exposes the ASGI callable as a module-level variable named application.
For more information on this file, see https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
1""" 2ASGI config for authentik project. 3 4It exposes the ASGI callable as a module-level variable named ``application``. 5 6For more information on this file, see 7https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8""" 9 10import django 11from channels.routing import ProtocolTypeRouter, URLRouter 12from django.core.asgi import get_asgi_application 13from sentry_sdk.integrations.asgi import SentryAsgiMiddleware 14 15from authentik.root.setup import setup 16 17# DJANGO_SETTINGS_MODULE is set in gunicorn.conf.py 18 19setup() 20django.setup() 21 22 23from authentik.root import websocket # noqa 24 25 26class LifespanApp: 27 """ 28 temporary shim for https://github.com/django/channels/issues/1216 29 needed so that hypercorn doesn't display an error. 30 this uses ASGI 2.0 format, not the newer 3.0 single callable 31 """ 32 33 def __init__(self, scope): 34 self.scope = scope 35 36 async def __call__(self, receive, send): 37 if self.scope["type"] == "lifespan": 38 while True: 39 message = await receive() 40 if message["type"] == "lifespan.startup": 41 await send({"type": "lifespan.startup.complete"}) 42 elif message["type"] == "lifespan.shutdown": 43 await send({"type": "lifespan.shutdown.complete"}) 44 return 45 46 47class RouteNotFoundMiddleware: 48 """Middleware to ignore 404s for websocket requests 49 taken from https://github.com/django/daphne/issues/165#issuecomment-808284950""" 50 51 def __init__(self, app): 52 self.app = app 53 54 async def __call__(self, scope, receive, send): 55 try: 56 return await self.app(scope, receive, send) 57 except ValueError as exc: 58 if "No route found for path" in str(exc) and scope["type"] == "websocket": 59 await send({"type": "websocket.close"}) 60 else: 61 raise exc 62 63 64class AuthentikAsgi(SentryAsgiMiddleware): 65 """Root ASGI App wrapper""" 66 67 def call_startup(self): 68 from authentik.root.signals import post_startup, pre_startup, startup 69 70 pre_startup.send(sender=self) 71 startup.send(sender=self) 72 post_startup.send(sender=self) 73 74 75application = AuthentikAsgi( 76 ProtocolTypeRouter( 77 { 78 "http": get_asgi_application(), 79 "websocket": RouteNotFoundMiddleware(URLRouter(websocket.websocket_urlpatterns)), 80 "lifespan": LifespanApp, 81 } 82 ) 83)
class
LifespanApp:
27class LifespanApp: 28 """ 29 temporary shim for https://github.com/django/channels/issues/1216 30 needed so that hypercorn doesn't display an error. 31 this uses ASGI 2.0 format, not the newer 3.0 single callable 32 """ 33 34 def __init__(self, scope): 35 self.scope = scope 36 37 async def __call__(self, receive, send): 38 if self.scope["type"] == "lifespan": 39 while True: 40 message = await receive() 41 if message["type"] == "lifespan.startup": 42 await send({"type": "lifespan.startup.complete"}) 43 elif message["type"] == "lifespan.shutdown": 44 await send({"type": "lifespan.shutdown.complete"}) 45 return
temporary shim for https://github.com/django/channels/issues/1216 needed so that hypercorn doesn't display an error. this uses ASGI 2.0 format, not the newer 3.0 single callable
class
RouteNotFoundMiddleware:
48class RouteNotFoundMiddleware: 49 """Middleware to ignore 404s for websocket requests 50 taken from https://github.com/django/daphne/issues/165#issuecomment-808284950""" 51 52 def __init__(self, app): 53 self.app = app 54 55 async def __call__(self, scope, receive, send): 56 try: 57 return await self.app(scope, receive, send) 58 except ValueError as exc: 59 if "No route found for path" in str(exc) and scope["type"] == "websocket": 60 await send({"type": "websocket.close"}) 61 else: 62 raise exc
Middleware to ignore 404s for websocket requests taken from https://github.com/django/daphne/issues/165#issuecomment-808284950
class
AuthentikAsgi(sentry_sdk.integrations.asgi.SentryAsgiMiddleware):
65class AuthentikAsgi(SentryAsgiMiddleware): 66 """Root ASGI App wrapper""" 67 68 def call_startup(self): 69 from authentik.root.signals import post_startup, pre_startup, startup 70 71 pre_startup.send(sender=self) 72 startup.send(sender=self) 73 post_startup.send(sender=self)
Root ASGI App wrapper
application =
<AuthentikAsgi object>