OpenAPI Schema generation fails with generic APIViews
qianxuanyon opened this issue · 4 comments
Description of the Bug Report
class LogoutView(APIView):
passErrors when accessing documents
AttributeError: 'LogoutView' object has no attribute 'get_serializer'
Is fault tolerance possible when the program has api in other formats
Checklist
- Certain that this is a bug (if unsure or you have a question use discussions instead)
- Code snippet or unit test added to reproduce bug
Could you provide the full stacktrace of the error? Thanks.
[01/Jun/2022 09:26:01] "GET /redoc/ HTTP/1.1" 200 625
Internal Server Error: /openapi
Traceback (most recent call last):
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/schemas/views.py", line 48, in handle_exception
return super().handle_exception(exc)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/schemas/views.py", line 37, in get
schema = self.schema_generator.get_schema(request, self.public)
File "/Users/lidaoran/dev/django-rest-framework-json-api/rest_framework_json_api/schemas/openapi.py", line 266, in get_schema
schema = super().get_schema(request, public)
File "/Users/lidaoran/opt/anaconda3/lib/python3.9/site-packages/rest_framework/schemas/openapi.py", line 81, in get_schema
operation = view.schema.get_operation(path, method)
File "/Users/lidaoran/dev/django-rest-framework-json-api/rest_framework_json_api/schemas/openapi.py", line 429, in get_operation
self._add_get_collection_response(operation)
File "/Users/lidaoran/dev/django-rest-framework-json-api/rest_framework_json_api/schemas/openapi.py", line 494, in _add_get_collection_response
"200": self._get_toplevel_200_response(operation, collection=True)
File "/Users/lidaoran/dev/django-rest-framework-json-api/rest_framework_json_api/schemas/openapi.py", line 518, in _get_toplevel_200_response
"items": self._get_reference(self.view.get_serializer()),
AttributeError: 'LogoutView' object has no attribute 'get_serializer'This is my configuration
urls.py
urlpatterns = [
path(
"openapi",
get_schema_view(
title="Example API",
description="API for all things …",
version="1.0.0",
generator_class=SchemaGenerator,
),
name="openapi-schema",
),
path('redoc/', TemplateView.as_view(
template_name='redoc.html',
extra_context={'schema_url':'openapi-schema'}
), name='redoc'),
]This is the source code of the object reporting the error
class LogoutView(APIView):
"""
Calls Django logout method and delete the Token object
assigned to the current User object.
Accepts/Returns nothing.
"""
permission_classes = (AllowAny,)
throttle_scope = 'dj_rest_auth'
def get(self, request, *args, **kwargs):
if getattr(settings, 'ACCOUNT_LOGOUT_ON_GET', False):
response = self.logout(request)
else:
response = self.http_method_not_allowed(request, *args, **kwargs)
return self.finalize_response(request, response, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.logout(request)
def logout(self, request):
try:
request.user.auth_token.delete()
except (AttributeError, ObjectDoesNotExist):
pass
if getattr(settings, 'REST_SESSION_LOGIN', True):
django_logout(request)
response = Response(
{'detail': _('Successfully logged out.')},
status=status.HTTP_200_OK,
)
return responseThanks for the additional information. So this seems to be an issue with our openapi implementation. As far as I see does the DRF implementation skip views without serializers.
We need to go through our openapi.py and all view.get_serializer() call need to be changed to either self.get_request_serializer or self.get_response_serializer. If None is returned, that view will need to be ignored.
Any PR is welcome.
With version 7.1.0 we deprecated the OpenAPI schema support integrated in DJA following the decision in DRF which did the same. We encourage using drf-spectacular-json-api to generate OpenAPI schemas.
I am not sure whether drf-spectacular-json-api works with generic APIView, but best is to check it out and if not raise an issue there. As schema generation support is deprecated, in DJA we won't make any changes to the schema generation unless it is very critical. Therefore, closing this issue.
Let me know if there are any questions though about the decision or how to move forward.