在使用python写web框架时,经常会碰到需要对request参数进行检验或者过滤,如果将诸多的校验逻辑都堆积在业务逻辑中,会显得很臃肿,在flask中,推荐一个很棒的库,可以写法变得很清晰.
比如有这么个需求: 在flask中,有个app route需要验证requests的post中body传递过来的token字段必须在配置文件中才合法,同时phone字段需要符合规则,再同时,除了必要的字段外,不能有其它的字段,如果出现其它的字段,但返回指定的错误码.
如果在代码中直接写各种判断也是ok,之前作者也常是这么做,但明显不够优雅,引入flask-apispec就可以很好的解决问题,让代码看上去很简洁.
1 | #!/usr/local/bin/python |
其它的也没什么,重要的只的@use_kwargs
装饰器,接下来详细展开
1 |
|
如果按照正常的写法一般是
1 |
|
在函数中直接使用request.json()
获取body的key-value, 然后做各种判断
那现在主函数webhook_dingtalk(**kw)
非常简短,答案就在引入了use_kwargs
,简单来讲就是use_kwargs
将接收request的参数,然后将参数作用于第一个参数指定的字典,即args_dt
,简单看一下args_dt
1 | args_dt = {"token": fields.Str(required=True, validate=must_exist_in_conf), "content": fields.Str(required=True), "to": fields.Str(load_default="@all", validate=check_sender)} |
其实也是非常清晰,在这个字典中其它指定了参数列表,也指定了各个参数需要进行的判断,比如token字段,required=True,表明这个字段是必要的,validate则表示这个字段需要进行的逻辑处理, 那么这里就可以写各种业务上的判断了,其实内置了很多常用的一些规则,比如判断是不是布尔型fields.Boolean()
等等.
这种写法是不是让主函数看上去简洁了许多.
主函数webhook_dingtalk(**kw)
接收的参数只有kw, kw其它就是args_dt合法后传递过来,如果从requst中拿到的参数不符合args_dt中指定的任一规则,则会触发422或者400错误,将会调用代码最上面定义的handle_error自定义逻辑,这里是返回403错误
1 | def use_kwargs(args, locations=None, inherit=None, apply=None, **kwargs): |
另外, use_kwargs的第2个参数location,表示的是从http传递过来的参数是以什么方式呈现,可以选用(‘json’, ‘querystring’, ‘form’, ‘headers’, ‘cookies’, ‘files’)作为locations的值,因为参数可以放在body中,也可以放在header或者是cookies中,这个参数主要是告诉use_kwargs需要的参数保存在哪里.
flask-apispec内部用了webargs用于参数解析, marshmallow库用于返回响应,也用了apispec,还有一些很实用的功能,感兴趣的可以查看官网
使用flask-apispec, 代码看上去舒服多了