【问题标题】:flask-restx how to create parser from modelflask-restx 如何从模型创建解析器
【发布时间】:2021-11-24 05:06:33
【问题描述】:

我正在使用flask-restx 记录和格式化我的 api

我有一个应用程序,包括一个目录,其中包含以下格式的 json 模式:http://json-schema.org/draft-07/schema#
(在我的应用程序中,它们保存为 json 文件,在下面的示例中,我将其作为 dict 硬编码以简化示例)


使用架构,我想实现 3 个目标:
  1. 文档
  2. 根据要求进行验证
  3. 解析请求

使用@api.expect(request_model, validate=True)我设法实现了(1)和(2),但是我没有找到使用现有模式进行解析的方法,我不得不创建一个解析器对象reqparse.RequestParser(),并重写参数。
有没有办法从模型中创建RequestParser? (模型是从现有的 json 模式文件创建的)

这是我的代码:


from flask_restx import Api, inputs

api = Api(app, doc='/my_doc_path')


request_schema = {
    'type': 'object',
    'properties': {
        'param1': {'type': 'string'},
        'the_date': {"type": "string", "format": "date-time"},
    },
    'required': ['param1'],
}
request_model = api.schema_model('my_api_model', request_schema)

@api.route('/my_api/<string:id>')
class MyApi(Resource):


    @api.expect(request_model, validate=True)
    def post(self, id):
        """
        my cool app
        """
        parser = reqparse.RequestParser()
        parser.add_argument('param1', help='some param 1')
        parser.add_argument('the_date', type=inputs.datetime_from_iso8601, help='some date_time')
        args = parser.parse_args()
        do_something(args['param1'], args['the_date'])

有没有办法像这样:

parser = reqparse.RequestParser(request_model)
args = parser.parse_args()

?

【问题讨论】:

    标签: python flask flask-restx


    【解决方案1】:

    我最终编写了代码以从架构中生成解析器:

    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/<string:id>')
    class MyApi(Resource):
    
    
        @Rest.route('my_api_schema_name', validate=True)
        def post(self, args, id):
            do_something(args['param1'], args['the_date'])
    

    注意我写的装饰器会解析 args 并将它们传递给 post 函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 2022-01-16
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多