-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for custom type dispatcher #48
Changes from all commits
b622935
d6b529b
e53ec32
2038c64
5dee40e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
import six | ||
|
||
from cornice_swagger.util import body_schema_transformer, merge_dicts, trim | ||
from cornice_swagger.converters import TypeConversionDispatcher | ||
from cornice_swagger.converters import convert_schema, convert_parameter | ||
|
||
|
||
|
@@ -16,7 +17,8 @@ class CorniceSwaggerException(Exception): | |
class CorniceSwagger(object): | ||
"""Handles the creation of a swagger document from a cornice application.""" | ||
|
||
def __init__(self, services, def_ref_depth=0, param_ref=False, resp_ref=False): | ||
def __init__(self, services, def_ref_depth=0, param_ref=False, resp_ref=False, | ||
custom_type_converters=None, default_type_converter=None): | ||
""" | ||
:param services: | ||
List of cornice services to document. You may use | ||
|
@@ -33,11 +35,18 @@ def __init__(self, services, def_ref_depth=0, param_ref=False, resp_ref=False): | |
Defines if swagger responses should be put inline on the operation | ||
or on the responses section and referenced by JSON pointers. | ||
Default is inline. | ||
:param custom_type_converters: | ||
A dictionary mapping user defined cornice types to callables | ||
implementing cornice_swagger.converters.schema.TypeConverter iface | ||
:param default_type_converter: | ||
Default TypeConverter to use when there is no type registered for a | ||
cornice type. If it's not given and the type is not registered, | ||
cornice_swagger.converters.exceptions.NoSuchConverter is raised | ||
""" | ||
|
||
self.services = services | ||
|
||
self.definitions = DefinitionHandler(ref=def_ref_depth) | ||
typ_dispatcher = TypeConversionDispatcher(custom_type_converters, default_type_converter) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My feel is to do the same for the parameter dispatcher here, even if it doesn't take any additional parameters related to it on the |
||
self.definitions = DefinitionHandler(ref=def_ref_depth, typ_dispatcher=typ_dispatcher) | ||
self.parameters = ParameterHandler(self.definitions, | ||
ref=param_ref) | ||
self.responses = ResponseHandler(self.definitions, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The response handler might also use custom type dispatchers. |
||
|
@@ -309,14 +318,18 @@ class DefinitionHandler(object): | |
|
||
json_pointer = '#/definitions/' | ||
|
||
def __init__(self, ref=0): | ||
def __init__(self, ref=0, typ_dispatcher=TypeConversionDispatcher()): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a good reason to have to overwrite the whole There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason is that I needed to change the behaviour of the class TypeConversionDispatcher(object):
converters = defaultdict(lambda: StringTypeConverter)
converters.update({
colander.Boolean: BooleanTypeConverter,
colander.Date: DateTypeConverter,
colander.DateTime: DateTimeTypeConverter,
colander.Float: NumberTypeConverter,
colander.Integer: IntegerTypeConverter,
colander.Mapping: ObjectTypeConverter,
colander.Sequence: ArrayTypeConverter,
colander.String: StringTypeConverter,
colander.Time: TimeTypeConverter,
})
... I do realize that's not a common use case, so it's ok for me to go with a dict of type:converter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I see. But I still think that passing the dispatcher is a bit extreme. One solution that i think is a little more simple is to have Edit: I would probably use a default converter as well :) |
||
""" | ||
:param ref: | ||
The depth that should be used by self.ref when calling self.from_schema. | ||
""" | ||
|
||
self.definition_registry = {} | ||
self.ref = ref | ||
self.typ_dispatcher = typ_dispatcher | ||
|
||
def convert_schema(self, schema_node): | ||
return convert_schema(schema_node, self.typ_dispatcher) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just call the type dispatcher here, we don't need to go through convert_schema. |
||
|
||
def from_schema(self, schema_node, base_name=None): | ||
""" | ||
|
@@ -330,7 +343,7 @@ def from_schema(self, schema_node, base_name=None): | |
:rtype: dict | ||
Swagger schema. | ||
""" | ||
return self._ref_recursive(convert_schema(schema_node), self.ref, base_name) | ||
return self._ref_recursive(self.convert_schema(schema_node), self.ref, base_name) | ||
|
||
def _ref_recursive(self, schema, depth, base_name=None): | ||
""" | ||
|
@@ -515,7 +528,7 @@ def from_schema_mapping(self, schema_mapping): | |
response['schema'] = self.definitions.from_schema(field_schema) | ||
|
||
elif location in ('header', 'headers'): | ||
header_schema = convert_schema(field_schema) | ||
header_schema = self.definitions.convert_schema(field_schema) | ||
headers = header_schema.get('properties') | ||
if headers: | ||
# Response headers doesn't accept titles | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we have references to the dispatchers in the
CorniceSwagger
class, I would just remove these two and call the dispatchers directly from there.