Update changelog and clean up code

openapi3
Cristi Vîjdea 2017-12-18 14:06:31 +01:00
parent 06a461ec09
commit 6060192a89
5 changed files with 59 additions and 36 deletions

View File

@ -7,25 +7,27 @@ Changelog
**1.0.5** **1.0.5**
********* *********
- **FIX:** fixed a crash caused by having read-only Serializers nested by reference - **FIXED:** fixed a crash caused by having read-only Serializers nested by reference
- **FIX:** removed erroneous backslashes in paths when routes are generated using Django 2 - **FIXED:** removed erroneous backslashes in paths when routes are generated using Django 2
`path() <https://docs.djangoproject.com/en/2.0/ref/urls/#django.urls.path>`_ `path() <https://docs.djangoproject.com/en/2.0/ref/urls/#django.urls.path>`_
- **IMPROVEMENT:** updated ``swagger-ui`` to version 3.7.0 - **IMPROVED:** updated ``swagger-ui`` to version 3.7.0
- **IMPROVED:** ``FileField`` is now generated as an URL or file name in response Schemas
(:pr:`21`, thanks to :ghuser:`h-hirokawa`)
********* *********
**1.0.4** **1.0.4**
********* *********
- **FIX:** fixed improper generation of YAML references - **FIXED:** fixed improper generation of YAML references
- **FEATURE:** added ``query_serializer`` parameter to - **ADDED:** added ``query_serializer`` parameter to
:func:`@swagger_auto_schema <.swagger_auto_schema>` (:issue:`16`, :pr:`17`) :func:`@swagger_auto_schema <.swagger_auto_schema>` (:issue:`16`, :pr:`17`)
********* *********
**1.0.3** **1.0.3**
********* *********
- **FIX:** fixed bug that caused schema views returned from cache to fail (:issue:`14`) - **FIXED:** fixed bug that caused schema views returned from cache to fail (:issue:`14`)
- **FIX:** disabled automatic generation of response schemas for form operations to avoid confusing errors caused by - **FIXED:** disabled automatic generation of response schemas for form operations to avoid confusing errors caused by
attempting to shove file parameters into Schema objects attempting to shove file parameters into Schema objects
********* *********

View File

@ -4,6 +4,7 @@
# drf-yasg documentation build configuration file, created by # drf-yasg documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 10 15:20:34 2017. # sphinx-quickstart on Sun Dec 10 15:20:34 2017.
import os import os
import re
import sys import sys
import sphinx_rtd_theme import sphinx_rtd_theme
@ -216,40 +217,59 @@ drf_yasg.views.SchemaView = drf_yasg.views.get_schema_view(None)
# custom interpreted role for linking to GitHub issues and pull requests # custom interpreted role for linking to GitHub issues and pull requests
# use as :issue:`14` or :pr:`17` # use as :issue:`14` or :pr:`17`
gh_issue_uri = "https://github.com/axnsan12/drf-yasg/issues/%d" gh_issue_uri = "https://github.com/axnsan12/drf-yasg/issues/{}"
gh_pr_uri = "https://github.com/axnsan12/drf-yasg/pull/%d" gh_pr_uri = "https://github.com/axnsan12/drf-yasg/pull/{}"
gh_user_uri = "https://github.com/{}"
def sphinx_err(inliner, lineno, rawtext, msg):
msg = inliner.reporter.error(msg, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
def sphinx_ref(options, rawtext, text, ref):
set_classes(options)
node = nodes.reference(rawtext, text, refuri=ref, **options)
return [node], []
def role_github_user(name, rawtext, text, lineno, inliner, options=None, content=None):
options = options or {}
content = content or []
if not re.match(r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$", text):
return sphinx_err(inliner, lineno, rawtext, '"%s" is not a valid GitHub username.' % text)
ref = gh_user_uri.format(text)
text = '@' + utils.unescape(text)
return sphinx_ref(options, rawtext, text, ref)
def role_github_pull_request_or_issue(name, rawtext, text, lineno, inliner, options=None, content=None): def role_github_pull_request_or_issue(name, rawtext, text, lineno, inliner, options=None, content=None):
options = options or {} options = options or {}
content = content or [] content = content or []
try: try:
ghid = int(text) if int(text) <= 0:
if ghid <= 0:
raise ValueError raise ValueError
except ValueError: except ValueError:
msg = inliner.reporter.error( return sphinx_err(
'GitHub pull request or issue number must be a number greater than or equal to 1; ' inliner, lineno, rawtext,
'"%s" is invalid.' % text, line=lineno 'GitHub pull request or issue number must be a number greater than or equal to 1; "%s" is invalid.' % text
) )
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
# Base URL mainly used by inliner.rfc_reference, so this is correct:
if name == 'pr': if name == 'pr':
ref = gh_pr_uri ref = gh_pr_uri
elif name == 'issue': elif name == 'issue':
ref = gh_issue_uri ref = gh_issue_uri
else: else:
msg = inliner.reporter.error('unknown tag name for GitHub reference - "%s"' % name, line=lineno) return sphinx_err(inliner, lineno, rawtext, 'unknown role name for GitHub reference - "%s"' % name)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
ref = ref % ghid ref = ref.format(text)
set_classes(options) text = '#' + utils.unescape(text)
node = nodes.reference(rawtext, '#' + utils.unescape(text), refuri=ref, **options) return sphinx_ref(options, rawtext, text, ref)
return [node], []
roles.register_local_role('pr', role_github_pull_request_or_issue) roles.register_local_role('pr', role_github_pull_request_or_issue)
roles.register_local_role('issue', role_github_pull_request_or_issue) roles.register_local_role('issue', role_github_pull_request_or_issue)
roles.register_local_role('ghuser', role_github_user)

View File

@ -38,7 +38,6 @@ class EndpointEnumerator(_EndpointEnumerator):
:return: the unescaped path :return: the unescaped path
:rtype: str :rtype: str
""" """
original_path = path
clean_path = '' clean_path = ''
while path: while path:
match = PATH_PARAMETER_RE.search(path) match = PATH_PARAMETER_RE.search(path)

View File

@ -177,12 +177,15 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
description = description if swagger_object_type != openapi.Items else None # Items has no description either description = description if swagger_object_type != openapi.Items else None # Items has no description either
def SwaggerType(**instance_kwargs): def SwaggerType(**instance_kwargs):
if swagger_object_type == openapi.Parameter: if swagger_object_type == openapi.Parameter and 'required' not in instance_kwargs:
instance_kwargs['required'] = field.required instance_kwargs['required'] = field.required
if swagger_object_type != openapi.Items: if swagger_object_type != openapi.Items and 'default' not in instance_kwargs:
default = getattr(field, 'default', serializers.empty) default = getattr(field, 'default', serializers.empty)
if default is not serializers.empty: if default is not serializers.empty:
instance_kwargs['default'] = default instance_kwargs['default'] = default
if swagger_object_type == openapi.Schema and 'read_only' not in instance_kwargs:
if field.read_only:
instance_kwargs['read_only'] = True
instance_kwargs.update(kwargs) instance_kwargs.update(kwargs)
return swagger_object_type(title=title, description=description, **instance_kwargs) return swagger_object_type(title=title, description=description, **instance_kwargs)
@ -214,8 +217,6 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
required = [] required = []
for key, value in serializer.fields.items(): for key, value in serializer.fields.items():
properties[key] = serializer_field_to_swagger(value, ChildSwaggerType, definitions) properties[key] = serializer_field_to_swagger(value, ChildSwaggerType, definitions)
if value.read_only and not isinstance(properties[key], openapi._Ref):
properties[key].read_only = value.read_only
if value.required: if value.required:
required.append(key) required.append(key)
@ -287,19 +288,20 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
elif isinstance(field, serializers.FileField): elif isinstance(field, serializers.FileField):
# swagger 2.0 does not support specifics about file fields, so ImageFile gets no special treatment # swagger 2.0 does not support specifics about file fields, so ImageFile gets no special treatment
# OpenAPI 3.0 does support it, so a future implementation could handle this better # OpenAPI 3.0 does support it, so a future implementation could handle this better
err = SwaggerGenerationError("parameter of type file is supported only in a formData Parameter") err = SwaggerGenerationError("FileField is supported only in a formData Parameter or response Schema")
if swagger_object_type == openapi.Schema: if swagger_object_type == openapi.Schema:
# FileField.to_representation returns URL or file name # FileField.to_representation returns URL or file name
result = SwaggerType(type=openapi.TYPE_STRING, read_only=True) result = SwaggerType(type=openapi.TYPE_STRING, read_only=True)
if getattr(field, 'use_url', api_settings.UPLOADED_FILES_USE_URL): if getattr(field, 'use_url', api_settings.UPLOADED_FILES_USE_URL):
result.format = openapi.FORMAT_URI result.format = openapi.FORMAT_URI
return result return result
elif swagger_object_type != openapi.Parameter: elif swagger_object_type == openapi.Parameter:
param = SwaggerType(type=openapi.TYPE_FILE)
if param['in'] != openapi.IN_FORM:
raise err # pragma: no cover
return param
else:
raise err # pragma: no cover raise err # pragma: no cover
param = SwaggerType(type=openapi.TYPE_FILE)
if param['in'] != openapi.IN_FORM:
raise err # pragma: no cover
return param
elif isinstance(field, serializers.DictField) and swagger_object_type == openapi.Schema: elif isinstance(field, serializers.DictField) and swagger_object_type == openapi.Schema:
child_schema = serializer_field_to_swagger(field.child, ChildSwaggerType, definitions) child_schema = serializer_field_to_swagger(field.child, ChildSwaggerType, definitions)
return SwaggerType( return SwaggerType(

View File

@ -15,7 +15,7 @@ class ArticleSerializer(serializers.ModelSerializer):
model = Article model = Article
fields = ('title', 'body', 'slug', 'date_created', 'date_modified', fields = ('title', 'body', 'slug', 'date_created', 'date_modified',
'references', 'uuid', 'cover', 'cover_name') 'references', 'uuid', 'cover', 'cover_name')
read_only_fields = ('date_created', 'date_modified', 'cover') read_only_fields = ('date_created', 'date_modified')
lookup_field = 'slug' lookup_field = 'slug'
extra_kwargs = {'body': {'help_text': 'body serializer help_text'}} extra_kwargs = {'body': {'help_text': 'body serializer help_text'}}