1. 程式人生 > 其它 >flask介面引數校驗 jsonschema 的使用

flask介面引數校驗 jsonschema 的使用

開頭

flask介面開發中引數校驗可以用到的方法有很多,但是我比較喜歡跟前端的js檢驗類似,故選用到了 jsonschema 這個引數校驗的庫

Demo

下面是一個比較全的引數校驗的介面,日後方便參考 官方連結 http://json-schema.org/learn/getting-started-step-by-step

from jsonschema import validate, ValidationError # 匯入引數的包

@app.route('/login4', methods=['POST'])
def login4():
    body = request.get_json()
    try:
        validate(
            body,
            {
                "$schema": "http://json-schema.org/learn/getting-started-step-by-step",
                # 描述對應的JSON元素,title相對來說,更加簡潔
                "title": "book info",
                # 描述對應的JSON元素,description更加傾向於詳細描述相關資訊
                "description": "some information about book",
                # 該關鍵字用於限定待校驗JSON元素所屬的資料型別,取值可為:object,array,integer,number,string,boolean,null
                "type": "object",
                # 用於指定JSON物件中的各種不同key應該滿足的校驗邏輯,
                # 如果待校驗JSON物件中所有值都能夠通過該關鍵字值中定義的對應key的校驗邏輯,每個key對應的值,都是一個JSON Schema,則待校驗JSON物件通過校驗。
                "properties": {
                    "id": {
                        "description": "The unique identifier for a book",
                        "type": "integer",
                        "minimum": 1
                    },
                    "name": {
                        "description": "book name",
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 30
                    },
                    "info": {
                        "description": "simple information about book",
                        "type": "string",
                        "minLength": 10,
                        "maxLength": 60
                    },
                    "tips": {
                        "anyOf": [  # 滿足其中一個型別 就行
                            {"type": "string", "minLength": 10, "maxLength": 60}, 
                            {"type": "number", "minimum": 5.0}
                        ]
                    },
                    "price": {
                        "description": "book price",
                        "type": "number",
                        # 能被0.5整除
                        "multipleOf": 0.5,
                        # 這裡取等,5.0=<price<=99999.0
                        "minimum": 5.0,
                        "maximum": 99999.0,
                        # 若使用下面這兩個關鍵字則 5.0<price<99999.0
                        # "exclusiveMinimum": 5.0,
                        # "exclusiveMaximum": 99999.0
                    },
                    "tags": {
                        "type": "array",
                        "items": [
                            {
                                "type": "string",
                                "minLength": 2,
                                "maxLength": 8
                            },
                            {
                                "type": "number",
                                "minimum": 1.0
                            }
                        ],
                        # 待校驗JSON陣列第一個元素是string型別,且可接受的最短長度為5個字元,第二個元素是number型別,且可接受的最小值為10
                        # 剩餘的其他元素是string型別,且可接受的最短長度為2。
                        "additonalItems": {
                            "type": "string",
                            "miniLength": 2
                        },
                        # 至少一個
                        "miniItems": 1,
                        # 最多5個
                        "maxItems": 5,
                        # 值為true時,所有元素都具有唯一性時,才能通過校驗。
                        "uniqueItems": True
                    },
                    "date": {
                        "description": "書籍出版日期",
                        "type": "string",
                        # 可以是以下取值:date、date-time(時間格式)、email(郵件格式)、hostname(網站地址格式)、ipv4、ipv6、uri等。
                        # 使用format關鍵字時,在例項化validator時必須給它傳format_checker引數,值如:draft7_format_checker, 網址:
                        # https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft7Validator
                        "format": "date",
                    },
                    "bookcoding": {
                        "description": "書籍編碼",
                        "type": "string",
                        # 符合該關鍵字指定的正則表示式,才算通過校驗。
                        "pattern": "^[A-Z]+[a-zA-Z0-9]{12}$"
                    },
                    "other": {
                        "description": "其他資訊",
                        "type": "object",
                        "properties": {
                            "info1": {
                                "type": "string"
                            },
                            "info2": {
                                "type": "string"
                            }
                        }
                    }
                },
                # 指定了待校驗JSON物件可以接受的最少 一級key 的個數
                "minProperties": 3,
                # 指定了待校驗JSON物件可以接受的最多 一級key 的個數。
                "maxProperties": 7,
                # patternProperties物件的每一個一級key都是一個正則表示式,value都是一個JSON Schema。
                # 只有待校驗JSON物件中的一級key,通過與之匹配的patternProperties中的一級正則表示式,對應的JSON Schema的校驗,才算通過校驗。
                # 下面的JSON Schema表示, 所有以a開頭的一級key的value都必須是number,
                "patternProperties": {
                    "^a": {
                        "type": "number"
                    },
                },
                # 如果待校驗JSON物件中存在,既沒有在properties中被定義,又沒有在patternProperties中被定義,那麼這些一級key必須通過additionalProperties的校驗。
                "additionalProperties": {
                    "desc": {
                        "type": "string",
                        "minLength": 1
                    },
                },
                # 該關鍵字限制了JSON物件中必須包含哪些一級key。
                # 如果一個JSON物件中含有required關鍵字所指定的所有一級key,則該JSON物件能夠通過校驗。
                "required": ["id", "name", "info", "price"]
            })
    
    except ValidationError as e:
        msg = "json資料不符合schema規定:\n出錯欄位:{}\n提示資訊:{}".format(" --> ".join([i for i in e.path]), e.message)
        print(msg)
        return jsonify(status=500, msg=msg)
        
    print(body)
    title = body.get('title')
    return '1'

完。