@@ -1,5 +1,5 @@
|
||||
from django.conf import settings
|
||||
from rest_framework.settings import APISettings
|
||||
from rest_framework.settings import perform_import
|
||||
|
||||
SWAGGER_DEFAULTS = {
|
||||
'USE_SESSION_AUTH': True,
|
||||
@@ -30,16 +30,49 @@ REDOC_DEFAULTS = {
|
||||
|
||||
IMPORT_STRINGS = []
|
||||
|
||||
|
||||
class AppSettings(object):
|
||||
"""
|
||||
Stolen from Django Rest Framework, removed caching for easier testing
|
||||
"""
|
||||
|
||||
def __init__(self, user_settings, defaults, import_strings=None):
|
||||
self._user_settings = user_settings
|
||||
self.defaults = defaults
|
||||
self.import_strings = import_strings or []
|
||||
|
||||
@property
|
||||
def user_settings(self):
|
||||
return getattr(settings, self._user_settings, {})
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr not in self.defaults:
|
||||
raise AttributeError("Invalid setting: '%s'" % attr) # pragma: no cover
|
||||
|
||||
try:
|
||||
# Check if present in user settings
|
||||
val = self.user_settings[attr]
|
||||
except KeyError:
|
||||
# Fall back to defaults
|
||||
val = self.defaults[attr]
|
||||
|
||||
# Coerce import strings into classes
|
||||
if attr in self.import_strings:
|
||||
val = perform_import(val, attr)
|
||||
|
||||
return val
|
||||
|
||||
|
||||
#:
|
||||
swagger_settings = APISettings(
|
||||
user_settings=getattr(settings, 'SWAGGER_SETTINGS', {}),
|
||||
swagger_settings = AppSettings(
|
||||
user_settings='SWAGGER_SETTINGS',
|
||||
defaults=SWAGGER_DEFAULTS,
|
||||
import_strings=IMPORT_STRINGS,
|
||||
)
|
||||
|
||||
#:
|
||||
redoc_settings = APISettings(
|
||||
user_settings=getattr(settings, 'REDOC_SETTINGS', {}),
|
||||
redoc_settings = AppSettings(
|
||||
user_settings='REDOC_SETTINGS',
|
||||
defaults=REDOC_DEFAULTS,
|
||||
import_strings=IMPORT_STRINGS,
|
||||
)
|
||||
|
||||
@@ -39,9 +39,6 @@ VALIDATORS = {
|
||||
class _OpenAPICodec(object):
|
||||
media_type = None
|
||||
|
||||
#: Allows easier mocking of settings
|
||||
settings = swagger_settings
|
||||
|
||||
def __init__(self, validators):
|
||||
self._validators = validators
|
||||
|
||||
@@ -89,7 +86,7 @@ class _OpenAPICodec(object):
|
||||
:return: swagger spec as dict
|
||||
:rtype: OrderedDict
|
||||
"""
|
||||
swagger.security_definitions = self.settings.SECURITY_DEFINITIONS
|
||||
swagger.security_definitions = swagger_settings.SECURITY_DEFINITIONS
|
||||
return swagger
|
||||
|
||||
|
||||
|
||||
@@ -65,10 +65,10 @@ class OpenAPISchemaGenerator(object):
|
||||
view = self._gen.create_view(callback, method, request)
|
||||
overrides = getattr(callback, 'swagger_auto_schema', None)
|
||||
if overrides is not None:
|
||||
# decorated function based view must have its decorator information passed on to th re-instantiated view
|
||||
# decorated function based view must have its decorator information passed on to the re-instantiated view
|
||||
for method, _ in overrides.items():
|
||||
view_method = getattr(view, method, None)
|
||||
if view_method is not None:
|
||||
if view_method is not None: # pragma: no cover
|
||||
setattr(view_method.__func__, 'swagger_auto_schema', overrides)
|
||||
return view
|
||||
|
||||
@@ -137,7 +137,8 @@ class OpenAPISchemaGenerator(object):
|
||||
schema = auto_schema_cls(view, path, method, overrides, components)
|
||||
operations[method.lower()] = schema.get_operation(operation_keys)
|
||||
|
||||
paths[path] = openapi.PathItem(parameters=path_parameters, **operations)
|
||||
if operations:
|
||||
paths[path] = openapi.PathItem(parameters=path_parameters, **operations)
|
||||
|
||||
return openapi.Paths(paths=paths)
|
||||
|
||||
@@ -178,7 +179,7 @@ class OpenAPISchemaGenerator(object):
|
||||
try:
|
||||
model_field = model._meta.get_field(variable)
|
||||
except Exception:
|
||||
model_field = None
|
||||
model_field = None # pragma: no cover
|
||||
|
||||
if model_field is not None and model_field.help_text:
|
||||
description = force_text(model_field.help_text)
|
||||
|
||||
@@ -166,9 +166,9 @@ class SwaggerAutoSchema(object):
|
||||
parameters = OrderedDict(((param.name, param.in_), param) for param in parameters)
|
||||
manual_parameters = self.overrides.get('manual_parameters', None) or []
|
||||
|
||||
if any(param.in_ == openapi.IN_BODY for param in manual_parameters):
|
||||
if any(param.in_ == openapi.IN_BODY for param in manual_parameters): # pragma: no cover
|
||||
raise SwaggerGenerationError("specify the body parameter as a Schema or Serializer in request_body")
|
||||
if any(param.in_ == openapi.IN_FORM for param in manual_parameters):
|
||||
if any(param.in_ == openapi.IN_FORM for param in manual_parameters): # pragma: no cover
|
||||
if any(param.in_ == openapi.IN_BODY for param in parameters.values()):
|
||||
raise SwaggerGenerationError("cannot add form parameters when the request has a request schema; "
|
||||
"did you forget to set an appropriate parser class on the view?")
|
||||
|
||||
@@ -5,7 +5,6 @@ from coreapi.compat import urlparse
|
||||
from future.utils import raise_from
|
||||
from inflection import camelize
|
||||
|
||||
|
||||
TYPE_OBJECT = "object" #:
|
||||
TYPE_STRING = "string" #:
|
||||
TYPE_NUMBER = "number" #:
|
||||
@@ -212,7 +211,7 @@ class Paths(SwaggerDict):
|
||||
super(Paths, self).__init__(**extra)
|
||||
for path, path_obj in paths.items():
|
||||
assert path.startswith("/")
|
||||
if path_obj is not None:
|
||||
if path_obj is not None: # pragma: no cover
|
||||
self[path] = path_obj
|
||||
self._insert_extras__()
|
||||
|
||||
@@ -403,7 +402,7 @@ class Responses(SwaggerDict):
|
||||
"""
|
||||
super(Responses, self).__init__(**extra)
|
||||
for status, response in responses.items():
|
||||
if response is not None:
|
||||
if response is not None: # pragma: no cover
|
||||
self[str(status)] = response
|
||||
self.default = default
|
||||
self._insert_extras__()
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"_from": "swagger-ui-dist",
|
||||
"_id": "swagger-ui-dist@3.5.0",
|
||||
"_from": "swagger-ui-dist@3.6.1",
|
||||
"_id": "swagger-ui-dist@3.6.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-JuvzMRqaYP6dFwYS7tUoKmW8kiY=",
|
||||
"_integrity": "sha1-uzQgV/h2COTs2DlGMDSJxjYicgY=",
|
||||
"_location": "/swagger-ui-dist",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "swagger-ui-dist",
|
||||
"raw": "swagger-ui-dist@3.6.1",
|
||||
"name": "swagger-ui-dist",
|
||||
"escapedName": "swagger-ui-dist",
|
||||
"rawSpec": "",
|
||||
"rawSpec": "3.6.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
"fetchSpec": "3.6.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.5.0.tgz",
|
||||
"_shasum": "26ebf3311a9a60fe9d170612eed5282a65bc9226",
|
||||
"_spec": "swagger-ui-dist",
|
||||
"_where": "C:\\Projects\\drf_openapi",
|
||||
"_resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.6.1.tgz",
|
||||
"_shasum": "bb342057f87608e4ecd83946303489c636227206",
|
||||
"_spec": "swagger-ui-dist@3.6.1",
|
||||
"_where": "C:\\Projects\\drf-swagger",
|
||||
"bugs": {
|
||||
"url": "https://github.com/swagger-api/swagger-ui/issues"
|
||||
},
|
||||
@@ -68,5 +68,5 @@
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/swagger-api/swagger-ui.git"
|
||||
},
|
||||
"version": "3.5.0"
|
||||
"version": "3.6.1"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -89,6 +89,7 @@ def swagger_auto_schema(method=None, methods=None, auto_schema=None, request_bod
|
||||
it will automatically be converted into a :class:`.Schema`
|
||||
|
||||
"""
|
||||
|
||||
def decorator(view_method):
|
||||
data = {
|
||||
'auto_schema': auto_schema,
|
||||
@@ -165,6 +166,10 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
|
||||
def SwaggerType(**instance_kwargs):
|
||||
if swagger_object_type == openapi.Parameter:
|
||||
instance_kwargs['required'] = field.required
|
||||
if swagger_object_type != openapi.Items:
|
||||
default = getattr(field, 'default', serializers.empty)
|
||||
if default is not serializers.empty:
|
||||
instance_kwargs['default'] = default
|
||||
instance_kwargs.update(kwargs)
|
||||
return swagger_object_type(title=title, description=description, **instance_kwargs)
|
||||
|
||||
@@ -249,7 +254,7 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
|
||||
elif isinstance(field, serializers.RegexField):
|
||||
return SwaggerType(type=openapi.TYPE_STRING, pattern=find_regex(field))
|
||||
elif isinstance(field, serializers.SlugField):
|
||||
return SwaggerType(type=openapi.TYPE_STRING, format=openapi.FORMAT_SLUG)
|
||||
return SwaggerType(type=openapi.TYPE_STRING, format=openapi.FORMAT_SLUG, pattern=find_regex(field))
|
||||
elif isinstance(field, serializers.URLField):
|
||||
return SwaggerType(type=openapi.TYPE_STRING, format=openapi.FORMAT_URI)
|
||||
elif isinstance(field, serializers.IPAddressField):
|
||||
@@ -272,11 +277,6 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
|
||||
if swagger_object_type != openapi.Parameter:
|
||||
raise SwaggerGenerationError("parameter of type file is supported only in formData Parameter")
|
||||
return SwaggerType(type=openapi.TYPE_FILE)
|
||||
elif isinstance(field, serializers.JSONField):
|
||||
return SwaggerType(
|
||||
type=openapi.TYPE_STRING,
|
||||
format=openapi.FORMAT_BINARY if field.binary else None
|
||||
)
|
||||
elif isinstance(field, serializers.DictField) and swagger_object_type == openapi.Schema:
|
||||
child_schema = serializer_field_to_swagger(field.child, ChildSwaggerType, definitions)
|
||||
return SwaggerType(
|
||||
@@ -284,7 +284,7 @@ def serializer_field_to_swagger(field, swagger_object_type, definitions=None, **
|
||||
additional_properties=child_schema
|
||||
)
|
||||
|
||||
# TODO unhandled fields: TimeField DurationField HiddenField ModelField NullBooleanField?
|
||||
# TODO unhandled fields: TimeField DurationField HiddenField ModelField NullBooleanField? JSONField
|
||||
|
||||
# everything else gets string by default
|
||||
return SwaggerType(type=openapi.TYPE_STRING)
|
||||
@@ -302,7 +302,7 @@ def find_regex(regex_field):
|
||||
if isinstance(validator, RegexValidator):
|
||||
if regex_validator is not None:
|
||||
# bail if multiple validators are found - no obvious way to choose
|
||||
return None
|
||||
return None # pragma: no cover
|
||||
regex_validator = validator
|
||||
|
||||
# regex_validator.regex should be a compiled re object...
|
||||
|
||||
Reference in New Issue
Block a user