Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URLRouter with path() does not work with get_asgi_application() as a route #1964

Open
dvf opened this issue Jan 10, 2023 · 2 comments
Open

Comments

@dvf
Copy link

dvf commented Jan 10, 2023

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/'.
@dvf
Copy link
Author

dvf commented Jan 10, 2023

I figured it out, using re_path("", get_asgi_application()) works, but path("", get_asgi_application()) does not.

@carltongibson carltongibson changed the title URLRouter does not work with get_asgi_application() as a route URLRouter with path() does not work with get_asgi_application() as a route Jan 10, 2023
@jp-sft
Copy link

jp-sft commented Dec 18, 2023

up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants