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

AttributeError: object of class Schema has no attribute fields #11433

Closed
abhi1693 opened this issue Jan 8, 2023 · 3 comments · Fixed by #11482
Closed

AttributeError: object of class Schema has no attribute fields #11433

abhi1693 opened this issue Jan 8, 2023 · 3 comments · Fixed by #11482
Assignees
Labels
status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application

Comments

@abhi1693
Copy link
Member

abhi1693 commented Jan 8, 2023

NetBox version

v3.3.10

Python version

3.10

Steps to Reproduce

Write a ViewSet with create method. Add a swagger decorator on it as

from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated

class GetViewSet(ViewSet):
  permission_classes = [IsAuthenticated]

  @swagger_auto_schema(
    request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        required=['my_field'],
        properties={
            'my_field': openapi.Schema(
                type=openapi.TYPE_STRING
            )
        },
    )
  )
  def create(self, request):
    return Response({'works: True})

Expected Behavior

The swagger docs page should not crash

Observed Behavior

Internal Server Error: /api/docs/
Traceback (most recent call last):
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/openapi.py", line 110, in __getattr__
    return self[make_swagger_name(item)]
KeyError: 'fields'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 34, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/utils/decorators.py", line 133, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/decorators/vary.py", line 21, in inner_func
    response = func(*args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 94, in get
    schema = generator.get_schema(request, self.public)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 248, in get_schema
    paths, prefix = self.get_paths(endpoints, components, request, public)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 406, in get_paths
    operation = self.get_operation(view, path, prefix, method, components, request)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 448, in get_operation
    operation = view_inspector.get_operation(operation_keys)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/inspectors/view.py", line 32, in get_operation
    body = self.get_request_body_parameters(consumes)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/inspectors/view.py", line 71, in get_request_body_parameters
    serializer = self.get_request_serializer()
  File "/home/asaharan/PycharmProjects/netbox/netbox/utilities/custom_inspectors.py", line 32, in get_request_serializer
    if writable_class := self.get_writable_class(serializer):
  File "/home/asaharan/PycharmProjects/netbox/netbox/utilities/custom_inspectors.py", line 42, in get_writable_class
    fields = {} if hasattr(serializer, 'child') else serializer.fields
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/openapi.py", line 113, in __getattr__
    raise AttributeError("object of class " + type(self).__name__ + " has no attribute " + item)
AttributeError: object of class Schema has no attribute fields
Internal Server Error: /api/docs/
Traceback (most recent call last):
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/openapi.py", line 110, in __getattr__
    return self[make_swagger_name(item)]
KeyError: 'fields'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 34, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/utils/decorators.py", line 133, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/decorators/vary.py", line 21, in inner_func
    response = func(*args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 94, in get
    schema = generator.get_schema(request, self.public)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 248, in get_schema
    paths, prefix = self.get_paths(endpoints, components, request, public)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 406, in get_paths
    operation = self.get_operation(view, path, prefix, method, components, request)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 448, in get_operation
    operation = view_inspector.get_operation(operation_keys)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/inspectors/view.py", line 32, in get_operation
    body = self.get_request_body_parameters(consumes)
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/inspectors/view.py", line 71, in get_request_body_parameters
    serializer = self.get_request_serializer()
  File "/home/asaharan/PycharmProjects/netbox/netbox/utilities/custom_inspectors.py", line 32, in get_request_serializer
    if writable_class := self.get_writable_class(serializer):
  File "/home/asaharan/PycharmProjects/netbox/netbox/utilities/custom_inspectors.py", line 42, in get_writable_class
    fields = {} if hasattr(serializer, 'child') else serializer.fields
  File "/home/asaharan/PycharmProjects/netbox/venv/lib/python3.10/site-packages/drf_yasg/openapi.py", line 113, in __getattr__
    raise AttributeError("object of class " + type(self).__name__ + " has no attribute " + item)
AttributeError: object of class Schema has no attribute fields

image

@abhi1693 abhi1693 added the type: bug A confirmed report of unexpected behavior in the application label Jan 8, 2023
@abhi1693
Copy link
Member Author

abhi1693 commented Jan 8, 2023

Here is a fix

diff --git a/netbox/utilities/custom_inspectors.py b/netbox/utilities/custom_inspectors.py
index d87613b20..25358535d 100644
--- a/netbox/utilities/custom_inspectors.py
+++ b/netbox/utilities/custom_inspectors.py
@@ -27,7 +27,7 @@ class NetBoxSwaggerAutoSchema(SwaggerAutoSchema):
     def get_request_serializer(self):
         serializer = super().get_request_serializer()
 
-        if serializer is not None and self.method in self.implicit_body_methods:
+        if serializer is not None and not isinstance(serializer, openapi.Schema) and self.method in self.implicit_body_methods:
             if writable_class := self.get_writable_class(serializer):
                 if hasattr(serializer, 'child'):
                     child_serializer = self.get_writable_class(serializer.child)

@abhi1693
Copy link
Member Author

@jeremystretch Can I submit a PR for this? It's an issue on v3.4.2 as well

@jeremystretch
Copy link
Member

Sure; thanks!

jeremystretch added a commit that referenced this issue Jan 18, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants