Python webargs 模块的简单使用
作者:Xjng 发布时间:2021-02-27 11:56:04
webargs是一个用于解析和验证HTTP请求对象的Python库,内置了对流行web框架的支持,包括Flask、Django、Bottle、Tornado、Pyramid、webapp2、Falcon和aiohttp。下面看下Python webargs 模块详解。
一、安装
python3 -m pip install webargs
文档
二、基础特性
# encoding=utf-8
from flask import Flask
from webargs import fields
from webargs.flaskparser import use_args
app = Flask(__name__)
app.route("/")
@use_args({
"name": fields.Str(required=True),
"age": fields.Int(required=True),
}, location='query')
def index(args):
print('args', args)
return "Hello " + args["name"]
if __name__ == "__main__":
app.run(debug=1)
2.1. 使用
2.1.1 通过装饰器
@use_args({
"name": fields.Str(required=True),
"age": fields.Int(required=True),
}, location='query')
第一个参数是需要获取的字段名,类型,是否必须等的定义
location是指从哪里获取这些参数,默认是json,可选:
'querystring' (same as 'query')
'json'
'form'
'headers'
'cookies'
'files'
解析完后,把所有参数放在字典里面,传给下层函数
2.1.2 通过函数
args = parser.parse(user_args, request)
参数和装饰器一样,多了一传request
2.2 参数检查
from webargs import fields, validate
args_1 = {
# 必须参数,字符串类型
"username": fields.Str(required=True),
# validate
"password": fields.Str(validate=lambda p: len(p) >= 6),
"password": fields.Str(validate=validate.Length(min=6)),
# Default value when argument is missing
"display_per_page": fields.Int(missing=10),
# Repeated parameter, e.g. "/?nickname=Fred&nickname=Freddie"
"nickname": fields.List(fields.Str()),
# Delimited list, e.g. "/?languages=python,javascript"
"languages": fields.DelimitedList(fields.Str()),
# When value is keyed on a variable-unsafe name
# or you want to rename a key
"user_type": fields.Str(data_key="user-type"),
"start_day": fields.DateTime(required=True, format='%Y-%m-%d %X'),
"bool": fields.Bool(),
"email": fields.Email(),
"ip": fields.IP(),
"type": fields.Constant(constant='COMMON_TYPE'),
"money": fields.Decimal(),
"weight": fields.Float(),
"url": fields.URL(),
"uuid": fields.UUID(),
"raw": fields.Raw(),
}
fields.Str 表示接收字符串参数
required=True 表示必传
validate=lambda p: len(p) >= 6 表示自定义检查函数。会把参数传递给该函数,该函数返回True表示检查通过,返回False或者抛出异常表示检查不通过
如果要对多个参数进行联合检查,需要在装饰器层架validate参数:@use_args(args_1, validate=lambda args: len(args["username"]) < len(args["password"]))
异常需要是from webargs import ValidationError这个异常,不然会当程序异常处理
也可以用validate库里面的内置检查函数
missing=10 表示如果没有入参,设置为默认值
fields.List(fields.Str()) 表示列表型参数,列表的元素是字符串
fields.DelimitedList(fields.Str()) 表示逗号型的列表参数
data_key="user-type" 表示字段名修改,入参是user-type,在args字典会改为user_type
fields.DateTime(required=True, format='%Y-%m-%d %X') 表示接收日期类型,并且格式需要符合,参数值会转换为datetime类型
"bool": fields.Bool() 表示布尔类型,传1,0,true,false都能识别
fields.Email() 只接收email,估计里面会有正则检查
fields.IP() 只接收IP
fields.Constant(constant='COMMON_TYPE') 常量参数,无论入参是什么值,type永远等于COMMON_TYPE
fields.Decimal() 转换为Decimal类型
fields.Float() 转换为float类型
fields.URL() fields.UUID() 正则检查url格式或者uuid格式
fields.Raw 不检查参数类型
内置参数检查
validate=validate.Length(min=1,max=10) 检查字符串长度需要在某个区间
validate=validate.OneOf(['male', 'female']) 入参需要在枚举里面
2.3 检查失败处理
如果参数检查失败,会返回422响应,但是不会提示哪个参数有问题。我们可以通过Flask的异常处理机制,捕获这个异常,然后构造我们想要的返回
@app.errorhandler(422) # 捕获422和400的异常码
@app.errorhandler(400)
def handle_error(err):
headers = err.data.get("headers", None)
messages = err.data.get("messages", ["Invalid request."])
print(headers)
print(messages) # {'json': {'password': ['Shorter than minimum length 6.']}}
return json.dumps({'err_code': 10000, 'err_msg': messages['json']})
从err里面获取信息,headers不知道有什么用的,message会有异常信息,例如不满足
validate=validate.Length(min=6)
检查,就会返回{'json': {'password': ['Shorter than minimum length 6.']}}
如果是主动抛出的ValidationError异常,message会包含ValidationError异常的内容
我们可以把这个参数检查信息返回给前端,提示前端哪个参数错误了。
messages['json']
的json是location的key
2.4 嵌套参数
对于一些复杂的,有多重嵌套的参数
"name": fields.Nested(
{"first": fields.Str(required=True), "last": fields.Str(required=True)}
)
表示name是一个嵌套参数,也就是字典
然后里面需要要first key和last key
三、高级特性
3.1 自定义location
上面说了location支持query,json这些,也可以自定义
@parser.location_loader("data")
def load_data(request, schema):
data = {}
data.update({k: request.args.get(k) for k in request.args})
if request.json:
data.update({k: request.json.get(k) for k in request.json})
print(data, 'dataaaaa')
return data
parser.location = 'data' # 设置默认的location为data
上面定义了一个data的location,会合并args和json入参
把默认的location修改为data
也可以这样,这个是官方推荐方法:
@parser.location_loader("args_and_json")
def load_data(request, schema):
from webargs.multidictproxy import MultiDictProxy
newdata = request.args.copy()
if request.json:
newdata.update(request.json)
return MultiDictProxy(newdata, schema)
3.2 定义schema
除了可以通过字典定义args,也可以通过类:
from marshmallow import Schema
class UserSchema(Schema):
name = fields.Str(required=True)
age = fields.Int()
@app.route("/")
@use_args(UserSchema())
def index1(args):
print('args', args)
return "Hello "
3.3 未定义的参数处理
如果入参有未定义的参数,webargs默认会抛出422异常
from webargs.flaskparser import parser
import marshmallow
parser.unknown = marshmallow.EXCLUDE # 如果有未定义参数,不放到args参数,不抛异常
parser.unknown = marshmallow.INCLUDE # 如果有未定义参数,放到args参数,不抛异常
可以修改parse.unknown来修改策略。
也可以精确设置不同location的unknown策略
3.4 Flask的url参数
@app.route("/<int:id>/")
@use_args(UserSchema())
def index1(args, id):
print('args', args, id)
return "Hello "
如果需要用到Flask的url参数,就需要这样传递参数
来源:https://www.cnblogs.com/Xjng/p/15829657.html
猜你喜欢
- 自从SQL Server 2005推出后,因为有了更好的性能,所以有很多与SQL Server 2000相关的应用程序需要升级到这个版本。但
- 一、数据容器:list(列表)列表内的每一个数据,称之为元素以 [] 作为标识列表内每一个元素之间用, 逗号隔开定义语法:[元素1, 元素2
- 为了实现Nao机器人与电脑端的TCP通信,于是研究了一下Python实现TCP通信,在网上也看到了很多例子,但大多都是在一台机器上验证。在两
- time模块1:概述时间表示的分类时间戳格式化的时间字符串结构化时间时间戳:时间戳表示的是从1970年1月1日整0点到目前秒的偏移量,数据类
- 大家好,我是安果!目前公司使用 Jira 作为项目管理工具,在每一次迭代完成后的复盘会上,我们都需要针对本次迭代的&nb
- 介绍本文主要介绍Python中列表生成式的基本知识和使用生成列表要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10
- 在日常生活中我们经常在朋友圈看到有人发九宫格图片,其实质就是将一张图片切成九份,然后在微信中一起发这九张图。那么我们如何自己动手实现呢?说到
- 1.首先是html页面的form表单的三大属性,action是提交到哪,method是提交方式,enctype只要有图片上传就要加这个属性D
- 字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,
- 其实之前笔者写代码的时候用到模型的保存和加载,需要用的时候就去度娘搜一下大致代码,现在有时间就来整理下整个pytorch模型的保存和加载,开
- 用最新版本(2.1.0)的pyshp解析shp文件的records时:records = sf.records()如果records里面含有
- 在python3的sorted中去掉了cmp参数,转而推荐“key+lambda”的方式来排序。如果需要对python的list进行多级排序
- df.sort_index()实现按索引排序,默认以从小到大的升序方式排列,如希望按降序排列,传入ascending = Falseimpo
- 1.彻底弄懂CSS盒子模式一(DIV布局快速入门)3.彻底弄懂CSS盒子模式三(浮动的表演和清除的自述) 4.彻底弄懂CSS盒子模式四(绝对
- 最近使用python里的matplotlib库绘图,想在代码结束时显示图片看看,结果图片一闪而过,附上我原来代码:import matplo
- 编写 models.py 文件from django.db import models# Create your models here.c
- 1. 解决思路首先要获得这张验证码的图片,但是该图片一般都是用的js写的,不能够通过url进行下载。解决方案:截图然后根据该图片的定位和长高
- 大家觉得在接手遗留代码时,见到什么东东是最让人感到不耐烦的?复杂无比的 UML ?我觉得不是。我的答案是,超过两个 else 的 if ,或
- 一份基于cnn的手写数字自识别的代码,供大家参考,具体内容如下# -*- coding: utf-8 -*-import tensorflo
- ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(s