From ff9aa579571458fdfc8babb4fee0bef21062062a Mon Sep 17 00:00:00 2001 From: Jennings Zhang Date: Mon, 30 Sep 2024 21:52:04 -0400 Subject: [PATCH] Remove all vnd.collection+json content from OpenAPI spec --- .../collectionjson/spectacular_hooks.py | 32 +++++++++++++++++++ chris_backend/config/settings/common.py | 6 +++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 chris_backend/collectionjson/spectacular_hooks.py diff --git a/chris_backend/collectionjson/spectacular_hooks.py b/chris_backend/collectionjson/spectacular_hooks.py new file mode 100644 index 00000000..a1a64423 --- /dev/null +++ b/chris_backend/collectionjson/spectacular_hooks.py @@ -0,0 +1,32 @@ +from typing import Any + +def postprocess_remove_collectionjson(result, **_kwargs): + """ + Delete all `vnd.collection+json` content types from the given `result`. + + :param result: an OpenAPI specification + """ + for path in result['paths'].values(): + for operation in path.values(): + if 'parameters' in operation: + operation['parameters'] = [p for p in operation['parameters'] if not _is_format_qs(p)] + _del_collectionjson_content(operation.get('requestBody', {})) + for response in operation.get('responses', {}).values(): + _del_collectionjson_content(response) + return result + + +def _is_format_qs(parameter: dict[str, Any]): + return ( + parameter.get('in', None) == 'query' + and parameter.get('name', None) == 'format' + and parameter.get('schema', {}).get('type', None) == 'string' + and set(parameter.get('schema', {}).get('enum', [])) == {'collection+json', 'json'} + ) + + +def _del_collectionjson_content(x): + if 'content' not in x: + return + if 'application/vnd.collection+json' in x['content']: + del x['content']['application/vnd.collection+json'] diff --git a/chris_backend/config/settings/common.py b/chris_backend/config/settings/common.py index 1ee4de55..e173ce91 100755 --- a/chris_backend/config/settings/common.py +++ b/chris_backend/config/settings/common.py @@ -198,7 +198,11 @@ 'SERVE_INCLUDE_SCHEMA': True, 'COMPONENT_SPLIT_REQUEST': env.bool("SPECTACULAR_SPLIT_REQUEST", False), 'PREPROCESSING_HOOKS': [ - 'drf_spectacular.hooks.preprocess_exclude_path_format' + 'drf_spectacular.hooks.preprocess_exclude_path_format', + ], + 'POSTPROCESSING_HOOKS': [ + 'drf_spectacular.hooks.postprocess_schema_enums', + 'collectionjson.spectacular_hooks.postprocess_remove_collectionjson' ], 'SCHEMA_PATH_PREFIX': '/api/v1/',