Skip to content

Commit

Permalink
support "reqparser" on swagger.operation
Browse files Browse the repository at this point in the history
  • Loading branch information
dases committed Aug 26, 2014
1 parent 27aae64 commit 2ba24a0
Showing 1 changed file with 63 additions and 7 deletions.
70 changes: 63 additions & 7 deletions flask_restful_swagger/swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,15 +287,21 @@ def extract_operations(resource, path_arguments=[]):
op = {
'method': method,
'parameters': path_arguments,
'nickname': 'nickname'
'nickname': resource.__name__ + method_impl.__name__
}
op['summary'], op['notes'] = _parse_doc(method_impl)

if '__swagger_attr' in method_impl.__dict__:
# This method was annotated with @swagger.operation
decorators = method_impl.__dict__['__swagger_attr']
for att_name, att_value in list(decorators.items()):
if isinstance(att_value, (str, int, list)):
if att_name == 'reqparser':
# ensure a unique name if we need to create a model
model_name = decorators.get('nickname', op['nickname']) + 'Params'
op['parameters'] = merge_reqparse_args(op['parameters'],
att_value,
model_name)
elif isinstance(att_value, (str, int, list)):
if att_name == 'parameters':
op['parameters'] = merge_parameter_list(
op['parameters'], att_value)
Expand All @@ -309,6 +315,43 @@ def extract_operations(resource, path_arguments=[]):
return operations


def merge_reqparse_args(base, reqparser, model_name):
"""Translate a flask-restful RequestParser into swagger params.
If any of the reqparser args are location=json (which is the default)
then a model (named model_name) will be created with all json args.
"""
model = {'id': model_name, 'properties': {}, 'required': []}
register_model = False
params = []
for arg in reqparser.args:
if 'json' in arg.location:
register_model = True
if arg.required:
model['required'].append(arg.name)
model['properties'][arg.name] = reqparse_arg_to_swagger_param(arg)
else:
param = reqparse_arg_to_swagger_param(arg)
# note: "cookies" location not supported by swagger
if arg.location == 'args':
param['paramType'] = 'query'
elif arg.location == 'headers':
param['paramType'] = 'header'
elif arg.location == 'view_args':
param['paramType'] = 'path'
else:
param['paramType'] = arg.location
params.append(param)

if register_model:
registry['models'][model_name] = model
params.append({'name': 'body',
'paramType': 'body',
'dataType': model_name,
'required': len(model['required']) > 0
})
return merge_parameter_list(base, params)


def merge_parameter_list(base, override):
base = list(base)
names = [x['name'] for x in base]
Expand All @@ -322,6 +365,17 @@ def merge_parameter_list(base, override):
return base


def reqparse_arg_to_swagger_param(arg):
param = deduce_swagger_type(arg.type)
param['name'] = arg.name
param['description'] = arg.help
param['defaultValue'] = arg.default
param['required'] = arg.required
if arg.action == 'append':
param['allowMultiple'] = True
return param


class SwaggerRegistry(Resource):
def get(self):
req_registry = _get_current_registry()
Expand Down Expand Up @@ -469,6 +523,9 @@ def deduce_swagger_type_flat(python_type_or_object, nested_type=None):
fields.FormattedString,
fields.Url)):
return 'string'
if predicate(python_type_or_object, (bool,
fields.Boolean)):
return 'boolean'
if predicate(python_type_or_object, (int,
fields.Integer)):
return 'integer'
Expand All @@ -477,9 +534,6 @@ def deduce_swagger_type_flat(python_type_or_object, nested_type=None):
fields.Arbitrary,
fields.Fixed)):
return 'number'
if predicate(python_type_or_object, (bool,
fields.Boolean)):
return 'boolean'
if predicate(python_type_or_object, (fields.DateTime,)):
return 'date-time'

Expand Down Expand Up @@ -513,10 +567,12 @@ def split_arg(arg):
if len(spl) == 1:
return {'name': spl[0],
'dataType': 'string',
'paramType': 'path'}
'paramType': 'path',
'required': True}
else:
return {'name': spl[1],
'dataType': spl[0],
'paramType': 'path'}
'paramType': 'path',
'required': True}

return list(map(split_arg, args))

0 comments on commit 2ba24a0

Please sign in to comment.