from drf_yasg import openapi
from drf_yasg.inspectors import SwaggerAutoSchema
from drf_yasg.utils import filter_none, force_real_str


class CustomAutoSchema(SwaggerAutoSchema):
    def get_operation(self, operation_keys=None):
        operation_keys = operation_keys or self.operation_keys

        consumes = self.get_consumes()
        produces = self.get_produces()

        body = self.get_request_body_parameters(consumes)
        query = self.get_query_parameters()
        parameters = body + query
        parameters = filter_none(parameters)
        parameters = self.add_manual_parameters(parameters)

        operation_id = self.get_operation_id(operation_keys)
        summary, description = self.get_summary_and_description()
        security = self.get_security()
        assert security is None or isinstance(
            security, list
        ), "security must be a list of security requirement objects"
        deprecated = self.is_deprecated()
        tags = self.get_tags(operation_keys)

        responses = self.get_responses()

        return openapi.Operation(
            operation_id=operation_id,
            description=force_real_str(description),
            summary=force_real_str(summary),
            responses=responses,
            parameters=parameters,
            consumes=consumes,
            produces=produces,
            tags=tags,
            security=security,
            deprecated=deprecated,
            **{"x-code-samples": self.overrides.get("code_examples")}
        )

api/catalog/custom_auto_schema.py
from drf_yasg import openapi
from drf_yasg.inspectors import SwaggerAutoSchema
from drf_yasg.utils import filter_none, force_real_str


class CustomAutoSchema(SwaggerAutoSchema):
    def get_pagination_parameters(self):
        """
        Since the pagination params are a part of the ``MediaSearchRequestSerializer``,
        they need not be added again as pagination params.
        """

        return []

    def get_operation(self, operation_keys=None):
        operation_keys = operation_keys or self.operation_keys

        consumes = self.get_consumes()
        produces = self.get_produces()

        body = self.get_request_body_parameters(consumes)
        query = self.get_query_parameters()
        parameters = body + query
        parameters = filter_none(parameters)
        parameters = self.add_manual_parameters(parameters)

        operation_id = self.get_operation_id(operation_keys)
        summary, description = self.get_summary_and_description()
        security = self.get_security()
        assert security is None or isinstance(
            security, list
        ), "security must be a list of security requirement objects"
        deprecated = self.is_deprecated()
        tags = self.get_tags(operation_keys)

        responses = self.get_responses()

        return openapi.Operation(
            operation_id=operation_id,
            description=force_real_str(description),
            summary=force_real_str(summary),
            responses=responses,
            parameters=parameters,
            consumes=consumes,
            produces=produces,
            tags=tags,
            security=security,
            deprecated=deprecated,
            **{"x-code-samples": self.overrides.get("code_examples")}
        )

api/catalog/custom_auto_schema.py
diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml
index 5676ab79e..46d7d5f24 100644
--- a/.github/workflows/ci_cd.yml
+++ b/.github/workflows/ci_cd.yml
@@ -142,6 +142,10 @@ jobs:
       - name: Start API, ingest and index test data
         run: just init
 
+      - name: Smoke test ReDoc site
+        run: |
+          curl --fail 'http://localhost:8000/v1/?format=openapi'
+
       - name: Run API tests
         run: just api-test
 
diff --git a/api/catalog/custom_auto_schema.py b/api/catalog/custom_auto_schema.py
index 6e3b13b03..6cdbc94f4 100644
--- a/api/catalog/custom_auto_schema.py
+++ b/api/catalog/custom_auto_schema.py
@@ -4,6 +4,14 @@
 
 
 class CustomAutoSchema(SwaggerAutoSchema):
+    def get_pagination_parameters(self):
+        """
+        Since the pagination params are a part of the ``MediaSearchRequestSerializer``,
+        they need not be added again as pagination params.
+        """
+
+        return []
+
     def get_operation(self, operation_keys=None):
         operation_keys = operation_keys or self.operation_keys
 

Swagger/ReDoc page raises an error
## Description
<!-- Concisely describe the bug. Compare your experience with what you expected to happen. -->
<!-- For example: "I clicked the 'submit' button and instead of seeing a thank you message, I saw a blank page." -->
While deploying [v2.5.2](https://github.com/WordPress/openverse-api/releases/tag/v2.5.2) to staging, we noticed that the API documentation page failed to render and caused this error:

```
[2022-05-25 17:02:32,253 - django.request - 241][ERROR] Internal Server Error: /v1/
Traceback (most recent call last):
  File "/venv/lib/python3.10/site-packages/drf_yasg/openapi.py", line 110, in __getattr__
    return self[make_swagger_name(item)]
KeyError: 'name'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/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 "/venv/lib/python3.10/site-packages/sentry_sdk/integrations/django/views.py", line 67, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
  File "/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 34, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/venv/lib/python3.10/site-packages/django/utils/decorators.py", line 133, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/venv/lib/python3.10/site-packages/django/views/decorators/vary.py", line 21, in inner_func
    response = func(*args, **kwargs)
  File "/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/venv/lib/python3.10/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/venv/lib/python3.10/site-packages/drf_yasg/views.py", line 94, in get
    schema = generator.get_schema(request, self.public)
  File "/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 246, in get_schema
    paths, prefix = self.get_paths(endpoints, components, request, public)
  File "/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 404, in get_paths
    operation = self.get_operation(view, path, prefix, method, components, request)
  File "/venv/lib/python3.10/site-packages/drf_yasg/generators.py", line 446, in get_operation
    operation = view_inspector.get_operation(operation_keys)
  File "/api/catalog/custom_auto_schema.py", line 14, in get_operation
    query = self.get_query_parameters()
  File "/venv/lib/python3.10/site-packages/drf_yasg/inspectors/view.py", line 298, in get_query_parameters
    if len(set(param_list_to_odict(natural_parameters)) & set(param_list_to_odict(serializer_parameters))) != 0:
  File "/venv/lib/python3.10/site-packages/drf_yasg/utils.py", line 266, in param_list_to_odict
    result = OrderedDict(((param.name, param.in_), param) for param in parameters)
  File "/venv/lib/python3.10/site-packages/drf_yasg/utils.py", line 266, in <genexpr>
    result = OrderedDict(((param.name, param.in_), param) for param in parameters)
  File "/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 Parameter has no attribute name
```

Here's the error the page presents:
```
Something went wrong...
Error downloading http://localhost:8000/v1/?format=openapi HTTP ERROR 500

Stack trace

s/<@http://localhost:8000/static/drf-yasg/redoc/redoc.min.js:44:26651
read/</<@http://localhost:8000/static/drf-yasg/redoc/redoc.min.js:95:36080


s/<@http://localhost:8000/static/drf-yasg/redoc/redoc.min.js:44:26651
read/</<@http://localhost:8000/static/drf-yasg/redoc/redoc.min.js:95:35658

ReDoc Version: 2.0.0-rc.40
Commit: 17b9873
```

## Reproduction
<!-- Provide detailed steps to reproduce the bug. -->
1. `git checkout v2.5.2`
2. `just build`
3. `just recreate && just init`
4. Visit localhost:8000 and observe error

## Additional context
<!-- Add any other context about the problem here; or delete the section entirely. -->
Sentry issue: https://sentry.io/share/issue/83044216200d47538f3733a16df46adc/

## Resolution
<!-- Replace the [ ] with [x] to check the box. -->
- [ ] 🙋 I would be interested in resolving this bug.

