Solution
def build_parser(schema):
parser = RequestParser()
for prop, conf in schema['properties'].items():
if conf.get('type') == 'string' and conf.get('format') == 'date-time':
parser.add_argument(prop, type=inputs.datetime_from_iso8601)
elif conf['type'] == 'integer':
parser.add_argument(prop, type=int)
elif conf['type'] == 'boolean':
parser.add_argument(prop, type=bool, default=False)
elif conf['type'] == 'array':
parser.add_argument(prop, default=list, action='append')
else:
parser.add_argument(prop)
return parser
import functools
import inspect
class Rest:
@staticmethod
def route(api, route_str='', decorators=None):
decorators = decorators or []
def wrapper(cls):
for name, method in inspect.getmembers(cls, inspect.isfunction):
schema_name = getattr(method, '_schema_name', None)
if schema_name:
schema = getattr(method, '_schema', None)
setattr(cls, name, api.expect(api.schema_model(schema_name, schema), validate=True)(method))
cls.method_decorators = cls.method_decorators + decorators
return api.route(route_str)(cls) if route_str else cls
return wrapper
@staticmethod
def schema(schema_name, parse=False):
def decorator(f):
f._schema_name = schema_name
f._schema = get_api_schema(schema_name) # this function reads the json file
parser = build_parser(f._schema)
@functools.wraps(f)
def wrapper(*args, **kwargs):
if parse:
req_args = parser.parse_args()
return f(*args, req_args, **kwargs)
return f(*args, **kwargs)
return wrapper
return decorator
@Rest.route(api, '/my_api/')
class MyApi(Resource):
@Rest.schema('my_api_schema_name', parse=True)
def post(self, args, id):
do_something(args['param1'], args['the_date'])