bihealth / sodar-core

SODAR Core: A Django-based framework for building scientific data management web apps
MIT License
9 stars 1 forks source link

DRF generateschema command generates errors and warnings #1442

Closed holtgrewe closed 2 months ago

holtgrewe commented 2 months ago

Describe the Bug

After fixing #1440, the OpenAPI schema generator in DRF creates warnings similar to the one shown at the bottom:

You have a duplicated operationId in your OpenAPI schema

How to Reproduce

Apply #1441, then run python manage.py generateschema.

Expected Behavior

No warning should be produced.

Screenshots

N/A

System Information

Additional Context

/home/holtgrem_c/.local/share/virtualenvs/backend-_vbeNn7h/lib/python3.10/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: createAppAlertDismissAjax
        Route: /app_alerts/ajax/dismiss/{appalert}, Method: post
        Route: /app_alerts/ajax/dismiss/all, Method: post
        An operationId has to be unique across your schema. Your schema may not work in other tools.
mikkonie commented 2 months ago

Ajax views in SODAR Core are intended to be for client side UI use only. Hence, IMHO the proper solution is to set schema = None in base Ajax view classes.

mikkonie commented 2 months ago

It's not just warnings: when run for all SODAR Core apps we even get a proper crash from FileServeAPIView. That obviously doesn't have a serializer, so I need to also disable the schema there and any possibly similar views.

Dump:

Traceback (most recent call last):
  File "/home/mikkopen/code/sodar_core/./manage.py", line 29, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/management/commands/generateschema.py", line 43, in handle
    schema = generator.get_schema(request=None, public=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/schemas/openapi.py", line 81, in get_schema
    operation = view.schema.get_operation(path, method)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/schemas/openapi.py", line 147, in get_operation
    operation['operationId'] = self.get_operation_id(path, method)
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/schemas/openapi.py", line 267, in get_operation_id
    name = self.get_operation_id_base(path, method, action)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/schemas/openapi.py", line 232, in get_operation_id_base
    elif self.get_serializer(path, method) is not None:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/schemas/openapi.py", line 617, in get_serializer
    return view.get_serializer()
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/generics.py", line 108, in get_serializer
    serializer_class = self.get_serializer_class()
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mikkopen/.virtualenvs/sodar_core_django4/lib/python3.11/site-packages/rest_framework/generics.py", line 122, in get_serializer_class
    assert self.serializer_class is not None, (
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'FileServeAPIView' should either include a `serializer_class` attribute, or override the `get_serializer_class()` method.
mikkonie commented 2 months ago

Fixing the non-serializer view and omitting Ajax views from the schema still leaves me with the following, those have to be fixed individually it seems.

/xxx/lib/python3.11/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: retrieveAppSetting
    Route: /project/api/settings/retrieve/{project}, Method: get
    Route: /project/api/settings/retrieve/user, Method: get
    An operationId has to be unique across your schema. Your schema may not work in other tools.
  warnings.warn(
/xxx/lib/python3.11/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: retrieveFolder
    Route: /files/api/folder/list-create/{project}, Method: get
    Route: /files/api/folder/retrieve-update-destroy/{folder}, Method: get
    An operationId has to be unique across your schema. Your schema may not work in other tools.
  warnings.warn(
/xxx/lib/python3.11/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: retrieveFile
    Route: /files/api/file/list-create/{project}, Method: get
    Route: /files/api/file/retrieve-update-destroy/{file}, Method: get
    An operationId has to be unique across your schema. Your schema may not work in other tools.
  warnings.warn(
/xxx/lib/python3.11/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: retrieveHyperLink
    Route: /files/api/hyperlink/list-create/{project}, Method: get
    Route: /files/api/hyperlink/retrieve-update-destroy/{hyperlink}, Method: get
    An operationId has to be unique across your schema. Your schema may not work in other tools.
  warnings.warn(
/xxx/lib/python3.11/site-packages/rest_framework/schemas/openapi.py:49: UserWarning: You have a duplicated operationId in your OpenAPI schema: retrieveTimelineEvent
    Route: /timeline/api/list/{project}, Method: get
    Route: /timeline/api/retrieve/{timelineevent}, Method: get
    An operationId has to be unique across your schema. Your schema may not work in other tools.
  warnings.warn(
mikkonie commented 2 months ago

Fixed.