Skip to content

Commit

Permalink
Merge pull request #75 from Eastwu5788/wudong
Browse files Browse the repository at this point in the history
feature(): update docs for new version
  • Loading branch information
Eastwu5788 committed Apr 29, 2020
2 parents e17fd74 + 6bd037e commit 9327180
Show file tree
Hide file tree
Showing 18 changed files with 309 additions and 124 deletions.
33 changes: 21 additions & 12 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,36 @@
Version 2.0.9 (20200509)
-------------------------

- TODO: 强化处理数组类型参数能力
- TODO: 过滤器剥离为普通过滤器和复杂跨字段过滤器
Unreleased

- TODO: 强化处理数组类型参数能力
- TODO: 过滤器剥离为普通过滤器和复杂跨字段过滤器

Version 2.0.8 (20200430)
-------------------------

- 支持复杂数据结构字段校验
- 支持跨数据结构的字段互相验证
- 支持自定义验证结果存储键名称
Unreleased

- 支持复杂数据结构字段校验
- 支持跨数据结构的字段互相验证
- 支持自定义验证结果存储键名称
- 支持错误响应文字模糊化处理

Version 2.0.7
--------------

- 仅当用户在函数中填写`params`参数时才会进行函数参数赋值
- 新增`flask.g`传递格式化后的参数
- 变更 `direct_type` 参数名称为 `type`
- 变更 `key_map` 参数名称为 `dest`
Released 2020-04-23

- 仅当用户在函数中填写`params`参数时才会进行函数参数赋值
- 新增`flask.g`传递格式化后的参数
- 变更 `direct_type` 参数名称为 `type`
- 变更 `key_map` 参数名称为 `dest`

Version 2.0.6

Version 2.0.1
---------------

- 新增自定义响应,自定义过滤器,自定义格式化函数能力
- 新增大量跨字段验证方式
Released 2020-04-07

- 新增自定义响应,自定义过滤器,自定义格式化函数能力
- 新增大量跨字段验证方式
2 changes: 1 addition & 1 deletion DESCRIPTION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pre-request提供了非常方便的使用的方法,也提供了灵活的扩展
----

1. 提供绝大部分常用的参数基础验证能力,也提供callback函数让用户自定义验证
2. 提供跨字段的参数验证能力,实现两个字段关联验证
2. 提供跨字段的、跨数据结构的参数验证能力,实现参数之间关联验证
3. 提供响应对象、格式化函数、过滤器等核心组件的自定义能力
4. 详细完善的测试用例,保证整体测试覆盖率高于90%
5. 丰富的example,演示了pre-request目前提供的所有能力
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pre-request提供了非常方便的使用方法,也提供了灵活的扩展机
----

1. 提供绝大部分常用的参数基础验证能力,也提供callback函数让用户自定义验证
2. 提供跨字段的参数验证能力,实现两个字段关联验证
2. 提供跨字段的、跨数据结构的参数验证能力,实现参数之间关联验证
3. 提供响应对象、格式化函数、过滤器等核心组件的自定义能力
4. 详细完善的测试用例,保证整体测试覆盖率高于90%
5. 丰富的example,演示了pre-request目前提供的所有能力
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ rm -vrf ./build ./dist ./*.pyc ./*.tgz ./*.egg-info
./venv/bin/python setup.py sdist
./venv/bin/pip wheel --wheel-dir=./dist ./

./venv/bin/twine upload dist/*
#./venv/bin/twine upload dist/*
25 changes: 21 additions & 4 deletions docs/source/customize.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
自定义响应
自定义
===========

自定义响应
--------------

通常情况下,pre-request 检查用户参数发现问题时,会直接中断处理并将发现的问题返回给请求方。pre-request提供的
默认JSON响应格式如下:

Expand All @@ -24,7 +27,7 @@

class CusResponse(BaseResponse):

def __call__(self, formatter=None, error=None):
def __call__(self, fuzzy=False, formatter=None, error=None):
result = {
"code": error.code,
"rst": {}
Expand All @@ -44,7 +47,7 @@


自定义格式化内容
================
------------------

如果您觉得自定义一个响应类过于复杂,我们也提供了更轻便的自定义格式化函数功能,pre-request 在尝试拼接响应内容的时候,会优先尝试调用您的
格式化函数生成响应字符串。
Expand Down Expand Up @@ -72,7 +75,7 @@


自定义过滤器
===============
---------------

pre-request 提供了丰富的过滤器插件。但是面对各式各样的业务需求,您可能也觉得pre-request无法满足您。因此pre-request
提供了自定义过滤器功能,让您可以更加自身的业务需求去扩展pre-request框架。
Expand Down Expand Up @@ -115,3 +118,17 @@ pre-request 提供了丰富的过滤器插件。但是面对各式各样的业
from pre_request import pre

pre.add_filter(CustomFilter)


自定义参数存储
----------------

pre-request 在默认情况下会将格式化后的参数存储在 `~flask.g.params` 中和当前函数的 `params` 参数中。如果在您的项目中 `params` 字段有特殊
含义的话,您也可以自定义存储的参数名称。

::

from pre_request import pre

# 指定存储参数的key
pre.store_key = "pre_params"
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pre-request提供了非常方便的使用的方法,也提供了灵活的扩展
业务逻辑。


这部分文档将带您一步步使用pre-request框架。
本文档将带您一步步使用pre-request框架。

.. toctree::
:maxdepth: 2
Expand Down
5 changes: 3 additions & 2 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ pre-request 目前支持PyPi安装方式,您仅需使用pip命令即可安装
本地whl包
----------

当然您也可以在本地构建 whl 进行分发,我们提供了脚本供您一键构建,构建完成后 `dist` 文件夹下可以找到打包后的 whl 文件
当然您也可以在本地构建 whl 进行分发

.. code-block:: text
sh build.sh
python setup.py sdist
pip wheel --wheel-dir=./dist ./
37 changes: 37 additions & 0 deletions docs/source/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,43 @@ pre-request提供了非常方便的使用的方法,也提供了灵活的扩展
下面我们将挨个介绍pre-request支持的所有规则


location
-------------

`location` 当请求体,请求头或者其它位置有相同的参数时,您可以使用 `location` 限制位置进行读取。
目前支持的位置包括 ["args", "form", "values", "headers", "cookies", "json"]

::

# 限定参数从指定位置读取
params = {
"Access-Token": Rule(location="headers"),
"userId": Rule(location=["cookies", "headers", "args"])
}


deep
---------

`deep` 默认情况下,当前您的rule规则有层级关系时,pre-request会遵从您的层级关系从json中提取相同位置的参数进行填充。如果您指定了 `deep=False`
那么pre-request会放弃层级关系,直接从顶层参数中进行读取。

如果您不在json中传参数时,您可以使用 `.` 来标识层级关系。例如: `userInfo.socialInfo.age=13`

::

# 限定参数的层级关系
params = {
"userInfo": {
"userId": Rule(type=int, required=False),
"socialInfo": {
"gender": Rule(type=int, enum=[1, 2], default=1),
"age": Rule(type=int, gte=18, lt=80),
"country": Rule(required=True, deep=False)
}
}
}

type
-------------

Expand Down
94 changes: 11 additions & 83 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ pre-request最简单的使用方式
3. 使用 `@pre.catch(req_params)` 将参数规则赋值给装饰器,并装饰处理函数
4. 格式化后的参数置于 :class:`~flask.g` 中,同时尝试将格式化后的参数置于原函数的 `params` 参数中。


`pre` 单例介绍
---------------

pre-request 提供了一个全局单例 `pre` 对象,我们可以通过操作 `pre` 来修改pre-request的运行参数。

- `pre.fuzzy` 指示pre-request是否对参数验证错误原因进行模糊化处理。防止暴露过多信息
- `pre.sore_key` 自定义pre-request解析完成的参数的存储key
- `pre.content_type` 设置pre-request的错误响应格式,目前支持 `application/json` 和 `text/html`


`@pre.catch` 装饰器介绍
-------------------------

Expand Down Expand Up @@ -62,86 +73,3 @@ pre-request的过滤能力主要是通过`@pre.catch`装饰器来实现的
@pre.catch(get=get_field, post=post_field)
def all_handler(params):
return str(params)
Rule 规则介绍
--------------

:class:`~pre_request.Rule` 类是用来定义请求参数规则的类,目前支持以下规则

.. code-block:: python
# 字段目标数据类型
self.direct_type = kwargs.get("type", str)
# 不进行过滤,仅把参数加到结果集中
self.skip = kwargs.get("skip", False)
# 当前字段是否是必填项
self.required = kwargs.get("required", True)
self.required_with = kwargs.get("required_with", None)
# 当前字段默认值,如果不允许为空,则次字段无意义
self.default = kwargs.get("default", None)
# 去除前后的空格
self.trim = kwargs.get("trim", False)
# 字段枚举值设置
self.enum = kwargs.get("enum", list())
# 正则表达式
self.reg = kwargs.get("reg", None)
# Email判断
self.email = kwargs.get("email", False)
# 手机号判断
self.mobile = kwargs.get("mobile", False)
# 判断字符串中包含某个子串
self.contains = kwargs.get("contains", list())
# 判断字符串包含任意子串
self.contains_any = kwargs.get("contains_any", list())
# 判断字符串中禁止包括某个子串
self.excludes = kwargs.get("excludes", list())
# 判断字符串开头
self.startswith = kwargs.get("startswith", None)
# 判断字符串结尾
self.endswith = kwargs.get("endswith", None)
# 字符串小写
self.lower = kwargs.get("lower", False)
# 字符串大写
self.upper = kwargs.get("upper", False)
# 判断入参是否为ipv4/ipv6
self.ipv4 = kwargs.get("ipv4", False)
self.ipv6 = kwargs.get("ipv6", False)
self.mac = kwargs.get("mac", False)
# 判断入参是否为地理坐标 经度/维度
self.latitude = kwargs.get("latitude", False)
self.longitude = kwargs.get("longitude", False)
# 跨字段验证
self.eq_key = kwargs.get("eq_key", None)
self.neq_key = kwargs.get("neq_key", None)
self.gt_key = kwargs.get("gt_key", None)
self.gte_key = kwargs.get("gte_key", None)
self.lt_key = kwargs.get("lt_key", None)
self.lte_key = kwargs.get("lte_key", None)
# 等于/不等于
self.eq = kwargs.get("eq", None)
self.neq = kwargs.get("neq", None)
# 范围限定 direct_type 为数字时限定数字大小,为字符串时限定字符串长度
self.gt = kwargs.get("gt", None)
self.gte = kwargs.get("gte", None)
self.lt = kwargs.get("lt", None)
self.lte = kwargs.get("lte", None)
# key映射
self.key_map = kwargs.get("key_map", None)
# 是否需要进行json解析
self.json_load = kwargs.get("json", False)
# 自定义处理callback, 在所有的filter处理完成后,通过callback回调给用户进行自定义处理
self.callback = kwargs.get("callback", None)
2 changes: 1 addition & 1 deletion examples/example_flask/example_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class CustomResponse(BaseResponse):

def __call__(self, formatter=None, error=None):
def __call__(self, fuzzy=False, formatter=None, error=None):
"""
:type error: 错误
:return:
Expand Down
37 changes: 37 additions & 0 deletions examples/example_flask/example_store_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# !/usr/local/python/bin/python
# -*- coding: utf-8 -*-
# (C) Wu Dong, 2020
# All rights reserved
# @Author: 'Wu Dong <wudong@eastwu.cn>'
# @Time: '2020-04-28 10:12'
from flask import g, Flask
from pre_request import pre, Rule


app = Flask(__name__)
app.config["TESTING"] = True
client = app.test_client()


# 指定email=True,此时框架会自动判断用户入参是否符合email正则
args = {
"params": Rule(email=True)
}


pre.store_key = "test_params"


@app.route("/email", methods=["GET", "POST"])
@pre.catch(args)
def example_storage_handler(test_params):
print(g.test_params)
print(test_params)
return str(test_params)


if __name__ == "__main__":
resp = client.get("/email", data={
"params": "wudong@eastwu.cn"
})
print(resp.data)
8 changes: 6 additions & 2 deletions pre_request/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ def __init__(self, code, **context):
self.code = code
self.context = context

def form_message(self): # noqa: disable
def form_message(self, fuzzy=False): # noqa: disable
""" 格式化JSON格式的错误消息
"""
message = "参数检测失败,请检查您的输入!"
message = "参数验证失败,请检查您的输入!"

# 模糊错误信息
if fuzzy:
return message

# read filter object
filter_obj = self.context["filter"]
Expand Down
9 changes: 5 additions & 4 deletions pre_request/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ class PreRequest:
""" An object to dispatch filters to handler request params
"""

def __init__(self, store_key=None, content_type=None):
def __init__(self, fuzzy=False, store_key=None, content_type=None):
self.filters = simple_filters
self.complex_filters = complex_filters
self.fuzzy = fuzzy
self.content_type = content_type or "application/json"
self.store_key = store_key or "params"
self.response = None
Expand Down Expand Up @@ -272,9 +273,9 @@ def _f_resp(self, error):
:param error: ParamsValueError
"""
if self.response is not None:
return self.response()(self.formatter, error)
return self.response()(self.fuzzy, self.formatter, error)

if self.content_type == "text/html":
return HTMLResponse()(self.formatter, error)
return HTMLResponse()(self.fuzzy, self.formatter, error)

return JSONResponse()(self.formatter, error)
return JSONResponse()(self.fuzzy, self.formatter, error)

0 comments on commit 9327180

Please sign in to comment.