Search code examples
pythondjangoswaggerswagger-ui

Swagger with django - why am I getting a missing coreapi.Document error?


I'm trying to get a nice swagger UI working for a django webserver, but am running into a cryptic error.

urls.py

from django.urls import path
from djangofun import views
from rest_framework.schemas import get_schema_view
from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer

schema_view = get_schema_view(title='API', renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer])

urlpatterns = [
    path('', schema_view),
    path('hello/', views.hello)
]

views.py

from django.http import HttpResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET"])
def hello(request):
    return HttpResponse("Hello world")

The error, displayed as a webpage at localhost: The error I get when I load up localhost/

I am unsure how to correct this issue, perhaps I am missing something obvious? The documentation (that I found) didn't help. Note that if I remove the renderer_classes kwarg from the get_schema_view function, there is no error, but I am not given the swagger UI I am looking for.

Traceback:

Environment:


Request Method: GET
Request URL: http://localhost/

Django Version: 4.1
Python Version: 3.9.13
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework_swagger']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 220, in _get_response
    response = response.render()
  File "/usr/local/lib/python3.9/site-packages/django/template/response.py", line 114, in render
    self.content = self.rendered_content
  File "/usr/local/lib/python3.9/site-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/usr/local/lib/python3.9/site-packages/rest_framework_swagger/renderers.py", line 54, in render
    self.set_context(data, renderer_context)
  File "/usr/local/lib/python3.9/site-packages/rest_framework_swagger/renderers.py", line 68, in set_context
    renderer_context['spec'] = OpenAPIRenderer().render(
  File "/usr/local/lib/python3.9/site-packages/rest_framework_swagger/renderers.py", line 34, in render
    return OpenAPICodec().encode(data, **options)
  File "/usr/local/lib/python3.9/site-packages/rest_framework_swagger/renderers.py", line 16, in encode
    raise TypeError('Expected a `coreapi.Document` instance')

Exception Type: TypeError at /
Exception Value: Expected a `coreapi.Document` instance

Solution

  • I solved the issue. Ended up following this tutorial.

    urls.py

    from django.urls import path
    from djangofun import views
    from rest_framework.schemas import get_schema_view
    from django.views.generic import TemplateView
    
    urlpatterns = [
        path('openapi', get_schema_view(
            title="Your Project",
            description="API for all things …",
            version="1.0.0"
        ), name='openapi-schema'),
        path('', TemplateView.as_view(
            template_name='swagger-ui.html',
            extra_context={'schema_url':'openapi-schema'}
        ), name='swagger-ui'),
        path('hello/', views.hello)
    ]
    

    views.py

    from django.http import HttpResponse
    from django.views.decorators.http import require_http_methods
    from rest_framework.decorators import api_view
    
    @require_http_methods(["GET"])
    @api_view()
    def hello(request):
        return HttpResponse("Hello world")