djangodjango-rest-frameworkswaggerdjango-rest-framework-simplejwtdrf-spectacular

DRF spectacular not discovering custom auth extension classes


when extending a new Token Authentication class from rest_framework_simplejwt.authentication.JWTAuthentication drf-spectacular swagger-ui authorize button disappears and there is no way to add token bearer, I guess when you subclass it goes wrong.
steps to reproduce:
first, create a Django project with rest framework and drf-spectacular and simple jwt installed and configured with documentation guidance. got to /swagger-ui/ and it works fine.
then create a subclass of JWTAuthentication like below:

from rest_framework_simplejwt.authentication import JWTAuthentication as JWTA

class JWTAuthentication(JWTA):
    pass

and in your settings:

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'path_to_your_module.JWTAuthentication',
    ),
}

and now if you go to /swagger-ui/ there is no authorize button!!! how can I fix this?
and I even tried to create an AuthenticationExtension like:

from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme

class SimpleJWTTokenUserScheme(SimpleJWTScheme):
    target_class = 'path_to_your_module.JWTAuthentication'

but there is no way to register it anywhere nor on the internet nor in the documentation!! how can I fix authorize button when overriding an Authentication class??
Edit: doing what JPG says and importing extension in settings:

# settings.py
from path.to.custom.extension import SimpleJWTTokenUserScheme
REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'path_to_your_module.JWTAuthentication',
    ),
}

raises exception:

  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/views.py", line 67, in get
    return self._get_schema_response(request)
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/views.py", line 74, in _get_schema_response
    return Response(generator.get_schema(request=request, public=self.serve_public))
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/generators.py", line 250, in get_schema
    paths=self.parse(request, public),
  File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/generators.py", line 218, in parse
    assert isinstance(view.schema, AutoSchema), (
AssertionError: Incompatible AutoSchema used on View <class 'drf_spectacular.views.SpectacularAPIView'>. Is DRF's DEFAULT_SCHEMA_CLASS pointing to "drf_spectacular.openapi.AutoSchema" or any other drf-spectacular compatible AutoSchema?

Solution

  • Update-1

    from the doc Where should I put my extensions? / my extensions are not detected

    The extensions register themselves automatically. Just be sure that the python interpreter sees them at least once. To that end, we suggest creating a PROJECT/schema.py file and importing it in your PROJECT/__init__.py (same directory as settings.py and urls.py) with import PROJECT.schema. Please do not import the file in settings.py as this may potentially lead to cyclic import issues.


    Original Answer

    It seems a bug with the package itself. You can use the actual class instead of path to class while extending the auth extension

    from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme
    from path.to.custom.jwt.auth import JWTAuthentication
    
    class SimpleJWTTokenUserScheme(SimpleJWTScheme):
        target_class = JWTAuthentication

    I have created a simple example here, drf-spectacular-example, hope someone will benefit from it!!!