parent
af2a44e1e9
commit
174f1153b4
|
|
@ -54,7 +54,6 @@
|
||||||
</option>
|
</option>
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="PyShadowingNamesInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="PyShadowingNamesInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
||||||
<inspection_tool class="PyUnusedLocalInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false">
|
<inspection_tool class="PyUnusedLocalInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false">
|
||||||
<option name="ignoreTupleUnpacking" value="true" />
|
<option name="ignoreTupleUnpacking" value="true" />
|
||||||
<option name="ignoreLambdaParameters" value="true" />
|
<option name="ignoreLambdaParameters" value="true" />
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ drf\_yasg\.openapi
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
:exclude-members: _bare_SwaggerDict
|
||||||
|
|
||||||
drf\_yasg\.renderers
|
drf\_yasg\.renderers
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ class _OpenAPICodec(object):
|
||||||
:rtype: OrderedDict
|
:rtype: OrderedDict
|
||||||
"""
|
"""
|
||||||
swagger.security_definitions = swagger_settings.SECURITY_DEFINITIONS
|
swagger.security_definitions = swagger_settings.SECURITY_DEFINITIONS
|
||||||
return swagger
|
return swagger.as_odict()
|
||||||
|
|
||||||
|
|
||||||
class OpenAPICodecJson(_OpenAPICodec):
|
class OpenAPICodecJson(_OpenAPICodec):
|
||||||
|
|
@ -146,9 +146,24 @@ SaneYamlDumper.add_representer(OrderedDict, SaneYamlDumper.represent_odict)
|
||||||
SaneYamlDumper.add_multi_representer(OrderedDict, SaneYamlDumper.represent_odict)
|
SaneYamlDumper.add_multi_representer(OrderedDict, SaneYamlDumper.represent_odict)
|
||||||
|
|
||||||
|
|
||||||
|
def yaml_sane_dump(data, binary):
|
||||||
|
"""Dump the given data dictionary into a sane format:
|
||||||
|
|
||||||
|
* OrderedDicts are dumped as regular mappings instead of non-standard !!odict
|
||||||
|
* multi-line mapping style instead of json-like inline style
|
||||||
|
* list elements are indented into their parents
|
||||||
|
|
||||||
|
:param dict data: the data to be serializers
|
||||||
|
:param bool binary: True to return a utf-8 encoded binary object, False to return a string
|
||||||
|
:return: the serialized YAML
|
||||||
|
:rtype: str,bytes
|
||||||
|
"""
|
||||||
|
return yaml.dump(data, Dumper=SaneYamlDumper, default_flow_style=False, encoding='utf-8' if binary else None)
|
||||||
|
|
||||||
|
|
||||||
class OpenAPICodecYaml(_OpenAPICodec):
|
class OpenAPICodecYaml(_OpenAPICodec):
|
||||||
media_type = 'application/yaml'
|
media_type = 'application/yaml'
|
||||||
|
|
||||||
def _dump_dict(self, spec):
|
def _dump_dict(self, spec):
|
||||||
"""Dump ``spec`` into YAML."""
|
"""Dump ``spec`` into YAML."""
|
||||||
return yaml.dump(spec, Dumper=SaneYamlDumper, default_flow_style=False, encoding='utf-8')
|
return yaml_sane_dump(spec, binary=True)
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,13 @@ def make_swagger_name(attribute_name):
|
||||||
return camelize(attribute_name.rstrip('_'), uppercase_first_letter=False)
|
return camelize(attribute_name.rstrip('_'), uppercase_first_letter=False)
|
||||||
|
|
||||||
|
|
||||||
|
def _bare_SwaggerDict(cls):
|
||||||
|
assert issubclass(cls, SwaggerDict)
|
||||||
|
result = cls.__new__(cls)
|
||||||
|
OrderedDict.__init__(result) # no __init__ called for SwaggerDict subclasses!
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class SwaggerDict(OrderedDict):
|
class SwaggerDict(OrderedDict):
|
||||||
"""A particular type of OrderedDict, which maps all attribute accesses to dict lookups using
|
"""A particular type of OrderedDict, which maps all attribute accesses to dict lookups using
|
||||||
:func:`.make_swagger_name`. Attribute names starting with ``_`` are set on the object as-is and are not included
|
:func:`.make_swagger_name`. Attribute names starting with ``_`` are set on the object as-is and are not included
|
||||||
|
|
@ -108,11 +115,25 @@ class SwaggerDict(OrderedDict):
|
||||||
for attr, val in self._extras__.items():
|
for attr, val in self._extras__.items():
|
||||||
setattr(self, attr, val)
|
setattr(self, attr, val)
|
||||||
|
|
||||||
# noinspection PyArgumentList,PyDefaultArgument
|
@staticmethod
|
||||||
def __deepcopy__(self, memodict={}):
|
def _as_odict(obj):
|
||||||
result = OrderedDict(list(self.items()))
|
if isinstance(obj, dict):
|
||||||
result.update(copy.deepcopy(result, memodict))
|
result = OrderedDict()
|
||||||
return result
|
for attr, val in obj.items():
|
||||||
|
result[attr] = SwaggerDict._as_odict(val)
|
||||||
|
return result
|
||||||
|
elif isinstance(obj, (list, tuple)):
|
||||||
|
return type(obj)(SwaggerDict._as_odict(elem) for elem in obj)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def as_odict(self):
|
||||||
|
return SwaggerDict._as_odict(self)
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
# for pickle supprt; this skips calls to all SwaggerDict __init__ methods and relies
|
||||||
|
# on the already set attributes instead
|
||||||
|
return _bare_SwaggerDict, (type(self),), vars(self), None, iter(self.items())
|
||||||
|
|
||||||
|
|
||||||
class Contact(SwaggerDict):
|
class Contact(SwaggerDict):
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,10 @@ def plain_view(request):
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
|
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
|
||||||
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||||
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
|
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
|
||||||
|
url(r'^cached/swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=None), name='schema-json'),
|
||||||
|
url(r'^cached/swagger/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'),
|
||||||
|
url(r'^cached/redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
|
||||||
|
|
||||||
url(r'^admin/', admin.site.urls),
|
url(r'^admin/', admin.site.urls),
|
||||||
url(r'^snippets/', include('snippets.urls')),
|
url(r'^snippets/', include('snippets.urls')),
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ def validate_schema():
|
||||||
from flex.core import parse as validate_flex
|
from flex.core import parse as validate_flex
|
||||||
from swagger_spec_validator.validator20 import validate_spec as validate_ssv
|
from swagger_spec_validator.validator20 import validate_spec as validate_ssv
|
||||||
|
|
||||||
validate_flex(swagger)
|
validate_flex(copy.deepcopy(swagger))
|
||||||
validate_ssv(swagger)
|
validate_ssv(copy.deepcopy(swagger))
|
||||||
|
|
||||||
return validate_schema
|
return validate_schema
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
|
|
@ -46,6 +47,26 @@ def test_redoc(client, validate_schema):
|
||||||
_validate_text_schema_view(client, validate_schema, '/redoc/?format=openapi', json.loads)
|
_validate_text_schema_view(client, validate_schema, '/redoc/?format=openapi', json.loads)
|
||||||
|
|
||||||
|
|
||||||
|
def test_caching(client, validate_schema):
|
||||||
|
prev_schema = None
|
||||||
|
|
||||||
|
for i in range(3):
|
||||||
|
_validate_ui_schema_view(client, '/cached/redoc/', 'redoc/redoc.min.js')
|
||||||
|
_validate_text_schema_view(client, validate_schema, '/cached/redoc/?format=openapi', json.loads)
|
||||||
|
_validate_ui_schema_view(client, '/cached/swagger/', 'swagger-ui-dist/swagger-ui-bundle.js')
|
||||||
|
_validate_text_schema_view(client, validate_schema, '/cached/swagger/?format=openapi', json.loads)
|
||||||
|
|
||||||
|
json_schema = client.get('/cached/swagger.json')
|
||||||
|
assert json_schema.status_code == 200
|
||||||
|
json_schema = json.loads(json_schema.content.decode('utf-8'), object_pairs_hook=OrderedDict)
|
||||||
|
if prev_schema is None:
|
||||||
|
validate_schema(json_schema)
|
||||||
|
prev_schema = json_schema
|
||||||
|
else:
|
||||||
|
from datadiff.tools import assert_equal
|
||||||
|
assert_equal(prev_schema, json_schema)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.urls('urlconfs.non_public_urls')
|
@pytest.mark.urls('urlconfs.non_public_urls')
|
||||||
def test_non_public(client):
|
def test_non_public(client):
|
||||||
response = client.get('/private/swagger.yaml')
|
response = client.get('/private/swagger.yaml')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue