5

I have a Django REST Framework project and I'm trying to generate Swagger documentation. In my URL's file, however, I use a router and that doesn't seem to work very well with Swagger. I followed the instructions in this discussion and here's what I got:

This works perfectly:

router = CustomRouter(
    schema_title='My API',
    schema_renderers=[renderers.CoreJSONRenderer, OpenAPIRenderer],
    trailing_slash=False
)
router.register(r'users', UserViewSet, base_name='user')
router.register(r'foos', FooFieldViewSet)
router.register(r'bars', BarViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^session-auth/', include('rest_framework.urls')),
    url(r'^rest-auth/', include('rest_auth.urls')),
]

And I get the expected page:

expected page

If I add SwaggerUIRenderer to the schema_renderers list, however, it doesn't work anymore:

router = CustomRouter(
    schema_title='My API',
    schema_renderers=[renderers.CoreJSONRenderer, OpenAPIRenderer, SwaggerUIRenderer],
    trailing_slash=False
)
# ...

I get this page:

You do not have permission to perform this action

What am I doing wrong??

UPDATE

If I add ?format=swagger, I get:

/home/vagrant/ve/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango110Warning: django.core.context_processors is deprecated in favor of django.template.context_processors.
  return f(*args, **kwds)

[22/Jul/2016 09:00:10] "GET /?format=swagger HTTP/1.1" 403 3688
Internal Server Error: /
Traceback (most recent call last):
  File "/home/vagrant/ve/lib/python3.4/site-packages/django/core/handlers/base.py", line 174, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/vagrant/ve/lib/python3.4/site-packages/django/core/handlers/base.py", line 172, in get_response
    response = response.render()
  File "/home/vagrant/ve/lib/python3.4/site-packages/django/template/response.py", line 160, in render
    self.content = self.rendered_content
  File "/home/vagrant/ve/lib/python3.4/site-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, media_type, context)
  File "/home/vagrant/ve/lib/python3.4/site-packages/rest_framework_swagger/renderers.py", line 18, in render
    data = json.loads(codec.dump(data))
  File "/home/vagrant/ve/lib/python3.4/site-packages/openapi_codec/__init__.py", line 34, in dump
    data = generate_swagger_object(document)
  File "/home/vagrant/ve/lib/python3.4/site-packages/openapi_codec/encode.py", line 8, in generate_swagger_object
    parsed_url = urlparse.urlparse(document.url)
AttributeError: 'list' object has no attribute 'url'
[22/Jul/2016 09:00:10] "GET /?format=openapi HTTP/1.1" 500 81912
Ariel
  • 3,383
  • 4
  • 43
  • 58
  • It seems like you are not sending the `Authorization` header with this request. – Manjit Kumar Jul 21 '16 at 15:33
  • But how could adding `SwaggerUIRenderer` cause the `Authorization` header to get lost while using the default Browserable API? I'm not sure I was clear, the **ONLY** difference between the 2 scenarios is this one item in the list of `schema_renderers`. In the first scenario, everything works and I get no 403 error, so the `Authorization` header is clearly being sent properly. If I add the `SwaggerUIRenderer`, however, the Browserable API breaks and starts giving me 403. Besides, even in the broken scenario, my username still appears in the top bar, so I'm logged in. – Ariel Jul 22 '16 at 09:20

1 Answers1

0

At this point, the SwaggerUIRenderer does not override the default browsable API of the root view (html), so you have to specify the format query parameter to switch between renderers.

For example:

http://localhost:8000/?format=swagger -> Swagger UI interface

http://localhost:8000/?format=openapi-> Swagger/OpenAPI JSON spec

http://localhost:8000/?format=corejson -> CoreAPI CoreJSON

As for the 403, sounds like either an authentication config or you are not logged in.

Alternatively, remove the schema attributes of the router, and instead create a separate view that returns the schema.

Marc Gibbons
  • 1,190
  • 10
  • 5
  • Hey, thanks for the reply. I know about the `format` parameter, but the thing is, just by adding the Swagger renderer, the default Browserable API breaks and gives me 403. I suppose Swagger is just an extra option and I should still be able to access the Browserable API, right? But I can't. My username still appears at the top bar, I have the option to logout, but I get the 403 error in the json instead of the expected list of endpoints. – Ariel Jul 22 '16 at 09:11
  • If I create a separate view I don't get any errors but the endpoints that are added using the router simply don't show up. – Ariel Jul 22 '16 at 09:27