From 9d330d950926667cf61f2f89348ff78cdca5847c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20V=C3=AEjdea?= Date: Thu, 13 Sep 2018 04:18:55 +0300 Subject: [PATCH] Use the first line of view method docstring as Operation summary Closes #205. --- src/drf_yasg/inspectors/view.py | 26 +++++++++++++++++++++----- testproj/snippets/views.py | 4 ++++ tests/reference.yaml | 3 ++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/drf_yasg/inspectors/view.py b/src/drf_yasg/inspectors/view.py index 52b9319..b39cbf3 100644 --- a/src/drf_yasg/inspectors/view.py +++ b/src/drf_yasg/inspectors/view.py @@ -321,16 +321,32 @@ class SwaggerAutoSchema(ViewInspector): operation_id = '_'.join(operation_keys) return operation_id + def _extract_description_and_summary(self): + description = self.overrides.get('operation_description', None) + summary = self.overrides.get('operation_summary', None) + if description is None: + description = self._sch.get_description(self.path, self.method) or '' + description = description.strip().replace('\r', '') + + if description and (summary is None): + # description from docstring ... do summary magic + # https://www.python.org/dev/peps/pep-0257/#multi-line-docstrings + summary_max_len = 120 # OpenAPI 2.0 spec says summary should be under 120 characters + sections = description.split('\n\n', 1) + if len(sections) == 2: + sections[0] = sections[0].strip() + if len(sections[0]) < summary_max_len: + summary, description = sections + + return description, summary + def get_description(self): """Return an operation description determined as appropriate from the view's method and class docstrings. :return: the operation description :rtype: str """ - description = self.overrides.get('operation_description', None) - if description is None: - description = self._sch.get_description(self.path, self.method) - return description + return self._extract_description_and_summary()[0] def get_summary(self): """Return a summary description for this operation. @@ -338,7 +354,7 @@ class SwaggerAutoSchema(ViewInspector): :return: the summary :rtype: str """ - return self.overrides.get('operation_summary', None) + return self._extract_description_and_summary()[1] def get_security(self): """Return a list of security requirements for this operation. diff --git a/testproj/snippets/views.py b/testproj/snippets/views.py index f3978c3..aec28ad 100644 --- a/testproj/snippets/views.py +++ b/testproj/snippets/views.py @@ -46,6 +46,10 @@ class SnippetList(generics.ListCreateAPIView): ), ) def delete(self, *args, **kwargs): + """summary from docstring + + description body is here, summary is not included + """ pass diff --git a/tests/reference.yaml b/tests/reference.yaml index 5cc8c70..d7a6df8 100644 --- a/tests/reference.yaml +++ b/tests/reference.yaml @@ -391,7 +391,8 @@ paths: - snippets delete: operationId: snippetsDeleteBulk - description: SnippetList classdoc + summary: summary from docstring + description: description body is here, summary is not included parameters: - name: data in: body