vitalik / django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs
https://django-ninja.dev
MIT License
6.96k stars 420 forks source link

[BUG] no Response object generated for ASGI api route #1168

Open brendenwest opened 4 months ago

brendenwest commented 4 months ago

Describe the bug I'm running Django under ASGI and basic api routes are working fine. But when I follow the django-ninja documentation for an api route using a Schema response, I get this error:

'QuerySet' object has no attribute 'status_code'

requirements.txt

gunicorn==21.2.0
uvicorn[standard]==0.29.0
httptools==0.6.1
uvloop==0.20.0
asgiref==3.8.1

django==5.1.0
django-ninja==1.3.0

Dockerfile

FROM python:3.12
ENV PYTHONUNBUFFERED 1

RUN apt-get update && apt-get install -y \
    python3-pip python3-setuptools \
    openssl python3-service-identity python3-openssl \
    libyajl-dev libssl-dev

RUN mkdir /app
WORKDIR /app
ADD requirements.txt /app/
RUN pip install -r requirements.txt
ADD . /app/
RUN python manage.py
CMD ["uvicorn", "myApp.asgi:application", "--reload", "--host", "0.0.0.0", "--port", "8000"]

asgi.py

import os
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myApp.settings')

django_application = get_asgi_application()

async def application(scope, receive, send):
    if scope["type"] == "http":
        await django_application(scope, receive, send)

urls.py

from django.contrib import admin
from django.urls import path, re_path
from . import views

urlpatterns = [
    path('', views.home),
    path('admin/', admin.site.urls),
    re_path(r'^people/',  views.people),
]

views.py

from django.http import HttpRequest, HttpResponse, JsonResponse
from asgiref.sync import sync_to_async
from ninja import NinjaAPI, ModelSchema, Schema
from typing import List

from myApp.models import User

api = NinjaAPI()

class PersonSchema(ModelSchema):
    class Config:
        model = User
        model_fields = ["id", "username"]

@api.get("/people/", response=List[PersonSchema])
def people(request):
    return User.objects.all()

Versions (please complete the following information):

Traceback

024-05-16 10:36:25 Traceback (most recent call last):
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 518, in thread_handler
2024-05-16 10:36:25     raise exc_info[1]
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/django/core/handlers/exception.py", line 42, in inner
2024-05-16 10:36:25     response = await get_response(request)
2024-05-16 10:36:25                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/django/utils/deprecation.py", line 152, in __acall__
2024-05-16 10:36:25     response = await sync_to_async(
2024-05-16 10:36:25                ^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 468, in __call__
2024-05-16 10:36:25     ret = await asyncio.shield(exec_coro)
2024-05-16 10:36:25           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
2024-05-16 10:36:25     result = self.fn(*self.args, **self.kwargs)
2024-05-16 10:36:25              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 522, in thread_handler
2024-05-16 10:36:25     return func(*args, **kwargs)
2024-05-16 10:36:25            ^^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25   File "/usr/local/lib/python3.12/site-packages/django/middleware/common.py", line 107, in process_response
2024-05-16 10:36:25     if response.status_code == 404 and self.should_redirect_with_slash(request):
2024-05-16 10:36:25        ^^^^^^^^^^^^^^^^^^^^
2024-05-16 10:36:25 AttributeError: 'QuerySet' object has no attribute 'status_code'

Other traceback

image
brendenwest commented 3 months ago

Same behavior under Hypercorn

brendenwest commented 3 weeks ago

Still an issue under v 1.3.0

vitalik commented 3 weeks ago

Hi @brendenwest

Could you show how you initiated your api ? api = Router() ? api = NinjaAPI ? can you show more reproducible code

brendenwest commented 3 weeks ago

I've added more complete info from my views.py

brendenwest commented 2 weeks ago

Maybe related to this issue? - https://github.com/vitalik/django-ninja/issues/1277