tfranzel / drf-spectacular

Sane and flexible OpenAPI 3 schema generation for Django REST framework.
https://drf-spectacular.readthedocs.io
BSD 3-Clause "New" or "Revised" License
2.39k stars 264 forks source link

DistanceToPointOrderingFilter from restframework gis produces TypeError #1180

Open radudum10 opened 8 months ago

radudum10 commented 8 months ago

Describe the bug When including DistanceToPointOrderingFilter (source code an unhandled TypeError is raised, as you can see in this stack trace:

ERROR [246ae335101b4616b5f53e8d992048f9]:django.request: Internal Server Error: /api/schema (2024-02-21 13:15:03; log.py:241)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 534, in thread_handler
  raise exc_info[1]
File "/usr/local/lib/python3.12/site-packages/django/core/handlers/exception.py", line 42, in inner
  response = await get_response(request)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 534, in thread_handler
  raise exc_info[1]
File "/usr/local/lib/python3.12/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
  response = await wrapped_callback(
             ^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 479, in __call__
  ret: _R = await loop.run_in_executor(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/asgiref/current_thread_executor.py", line 40, in run
  result = self.fn(*self.args, **self.kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/asgiref/sync.py", line 538, in thread_handler
  return func(*args, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
  return view_func(*args, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
  return self.dispatch(request, *args, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/rest_framework/views.py", line 509, in dispatch
  response = self.handle_exception(exc)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/rest_framework/views.py", line 469, in handle_exception
  self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.12/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
  raise exc
File "/usr/local/lib/python3.12/site-packages/rest_framework/views.py", line 506, in dispatch
  response = handler(request, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/views.py", line 84, in get
  return self._get_schema_response(request)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/views.py", line 92, in _get_schema_response
  data=generator.get_schema(request=request, public=self.serve_pogor-backend-1    | ublic),
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/generators.py", line 281, in get_schema
  paths=self.parse(request, public),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/generators.py", line 252, in parse
  operation = view.schema.get_operation(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/openapi.py", line 91, in get_operation
  parameters = self._get_parameters()
               ^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/openapi.py", line 259, in _get_parameters
  **dict_helper(self._get_filter_parameters()),
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/drf_spectacular/openapi.py", line 547, in _get_filter_parameters
  parameters += filter_backend().get_schema_operation_parameters(self.view)
TypeError: 'NoneType' object is not iterable

I don't know if this is a bug or my implementation is faulty.

To Reproduce

Expected behavior If I remove the DistanceToPointOrderingFilter everything works as expected, so I would expect the same behaviour if I add this specific filter backend.

Judging by the line raising the exception, I think get_schema_operation_parameters somehow returns None. Maybe, it would be good a idea to handle the TypeError?

Thanks for developing this package!

tfranzel commented 8 months ago

Turns out they broke the interface by forgetting to return the param list from the method. Created a PR upstream:

https://github.com/openwisp/django-rest-framework-gis/pull/293

You could also hotfix it with an OpenApiFilterExtension that replaces that broken method in the meantime.

Not sure if we want to wrap this with a try/catch because we usually do not hide upstream bugs for obvious reasons.

radudum10 commented 8 months ago

Thanks for the PR and the fix suggestion! yep, it would be better to keep it how it is

nemesifier commented 8 months ago

Thanks for sending https://github.com/openwisp/django-rest-framework-gis/pull/293, it's merged :+1: