URLRouter with path() does not work with get_asgi_application() as a route
System
Python 3.11.0 / macOS Ventura 13.1
asgiref 3.6.0 ASGI specs, helper code, and adapters
async-timeout 4.0.2 Timeout context manager for asyncio programs
black 22.12.0 The uncompromising code formatter.
channels 4.0.0 Brings async, event-driven capabilities to Django 3.2 and up.
channels-redis 4.0.0 Redis-backed ASGI channel layer implementation
click 8.1.3 Composable command line interface toolkit
django 4.1.5 A high-level Python web framework that encourages rapid development and clean, pragmatic design.
gunicorn 20.1.0 WSGI HTTP Server for UNIX
h11 0.14.0 A pure-Python, bring-your-own-I/O implementation of HTTP/1.1
msgpack 1.0.4 MessagePack serializer
mypy-extensions 0.4.3 Experimental type system extensions for programs checked with the mypy typechecker.
pathspec 0.10.3 Utility library for gitignore style pattern matching of file paths.
platformdirs 2.6.2 A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir".
pydantic 1.10.4 Data validation and settings management using python type hints
redis 4.4.0 Python client for Redis database and key-value store
setuptools 65.6.3 Easily download, build, install, upgrade, and uninstall Python packages
sqlparse 0.4.3 A non-validating SQL parser.
typing-extensions 4.4.0 Backported and Experimental Type Hints for Python 3.7+
uvicorn 0.20.0 The lightning-fast ASGI server.
Bug
According to the documentation we should be able to do long-polling alongside regular Django views:
If you want to split HTTP handling between long-poll handlers and Django views, use a URLRouter using Django’s get_asgi_application() specified as the last entry with a match-everything pattern.
But it looks like path("", get_asgi_application()) does not route to regular Django views:
project/settings.py
...
ASGI_APPLICATION = "project.asgi.application"
ROOT_URLCONF = "project.urls"
project/asgi.py
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from django.urls import path
from my_app.consumers import SSEConsumer
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
application = ProtocolTypeRouter(
{
"http": URLRouter(
[
path("sse/<str:user_id>/", SSEConsumer.as_asgi()),
path("", get_asgi_application()),
]
)
}
)
project/urls.py
from django.contrib import admin
from django.http import HttpResponse
from django.urls import path
def test(request):
return HttpResponse("ok")
urlpatterns = [
path("test/", test),
path("admin/", admin.site.urls),
]
Running:
uvicorn project.asgi:application
Accessing http://localhost:8000/test/ results in an Exception:
INFO: 127.0.0.1:52810 - "GET /test/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/dvf/Library/Caches/pypoetry/virtualenvs/project-e3eQwoEC-py3.11/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dvf/Library/Caches/pypoetry/virtualenvs/project-e3eQwoEC-py3.11/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dvf/Library/Caches/pypoetry/virtualenvs/project-e3eQwoEC-py3.11/lib/python3.11/site-packages/channels/routing.py", line 62, in __call__
return await application(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dvf/Library/Caches/pypoetry/virtualenvs/project-e3eQwoEC-py3.11/lib/python3.11/site-packages/channels/routing.py", line 134, in __call__
raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'test/'.
I figured it out, using re_path("", get_asgi_application()) works, but path("", get_asgi_application()) does not.
up
middleware will help i think for this?
This is a duplicate of #1428. It's documented in the URLRouter docs:
Please note that URLRouter nesting will not work properly with path() routes if inner routers are wrapped by additional middleware.
@IronJam11 https://verification-pagan86.github.io/FTwO4tcCLBFPijpQzMmdmbGIm8WkwbFiV8usXFTZZ1Ip1aIIMA/