Skip to content
Danila Ganchar edited this page Jan 15, 2024 · 33 revisions

How to use

⚠️ Examples are using demo_error_handler ⚠️

Param description:

Param(
   name: the name of the request parameter
   param_type: where stored param(GET, FORM, JSON, PATH, HEADER)
   value_type: str, bool, int, float, dict, list - which type we want to have
   required: a bool that indicates whether a value is required, True by default
   default: the default value, None by default. You can use lambda for this arg - default=lambda: ['test']
   rule: the list of rules (see Rule class)
)

Note!(you can see the example below)

  • bool should be sent from client as: 1, 0, or true / false in any register
  • list should be sent from client as value1,value2,value3
  • dict should be sent from client as key1:val1,key2:val2

Example

from flask import Flask, jsonify
from flask_request_validator import *
from flask_request_validator.exceptions import *

app = Flask(__name__)
@app.errorhandler(RequestError)
def demo_error_handler(e):
    # customize error messages as you wish
    # see: https://github.com/d-ganchar/flask_request_validator/blob/4.3.1/flask_request_validator/exceptions.py#L221
    if isinstance(e, InvalidRequestError):
        return str(e.to_dict()), 400
    return str(e), 400

@app.route('/json/<string:uid>', methods=['POST'])
@validate_params(
    Param('colors', GET, list),
    Param('values', GET, dict),
    Param('uid', PATH, str, rules=CompositeRule(MinLength(3), MaxLength(5))),
    Param('dt', JSON, str, rules=[Datetime('%Y-%m-%d %H:%M:%S')]),
    Param('status', JSON, str, rules=[Enum('active', 'inactive')]),
    Param('name', JSON, str, rules=[Pattern(r'^[a-z]{4,20}$')]),
)
def json(valid: ValidRequest, uid):
    json_data = valid.get_json()
    json_data['dt'] = json_data['dt'].strftime('%Y-%m-%d')
    return jsonify({
        'get': valid.get_params(),
        'json': json_data,
        'path': valid.get_path_params(),
        'flask_url': valid.get_flask_request().url,
    })

🔴 Incorrect request:

# incorrect request
curl -H "Content-Type: application/json" \                                                                                                                                                                         
     --request POST --data '{}' \
     'http://localhost:5000/json/very_long?colors=green,yellow,blue&values=field1:val1,field2:val2'

# errors
{'path': {'uid': RulesError(ValueMaxLengthError(5))}, 'json': {'dt': RequiredValueError(), 'status': RequiredValueError(), 'name': RequiredValueError()}}

🟢 Correct request:

curl -H "Content-Type: application/json" \
     --request POST \
     -d '{"name":"test","status":"active","dt":"2020-01-02 03:04:05"}' \
     'http://localhost:5000/json/good?colors=green,yellow,blue&values=field1:val1,field2:val2'

# response
{
  "flask_url": "http://localhost:5000/json/good?colors=green,yellow,blue&values=field1:val1,field2:val2",
  "get": {
    "colors": [
      "green",
      "yellow",
      "blue"
    ],
    "values": {
      "field1": "val1",
      "field2": "val2"
    }
  },
  "json": {
    "dt": "2020-01-02",
    "name": "test",
    "status": "active"
  },
  "path": {
    "uid": "good"
  }
}

JFYI: you can move the parameters somewhere(just an example):

# route_params.user
USER_PARAMS = [
    Param('name', JSON, str, rules=[Pattern(r'^[a-z]{4,20}$')]),
    # ... other params
]
# in routes:
from routes_params.user import USER_PARAMS 

@app.route('/json/<string:uid>', methods=['POST'])
@validate_params(*USER_PARAMS)
def json(valid: ValidRequest, uid):
    # ...

Validation Rules

Rule Release Description
class MyRule(AbstractRule): ... 💙 1.0 provide possibility to write a custom rule
CompositeRule(Min(6), MyRule(6),... 💙 1.0 ability to combine rules
Pattern(r'^[a-z-_.]{8,10}$') 💙 1.0 value checks at regexp. Works only for str values
Enum('value1', 'value2') 💙 1.0 describes allowed values
MaxLength(6) / MinLength(6) 💙 1.0 value checks at max / min length. Works for str and list values
NotEmpty() 💚 3.0 checks that value is not empty. Works for str values and removes leading/trailing whitespace automatically
Max(6) / Min(6) 💛 4.0 checks that value is less or equal. Works for int and float
IsEmail() 💛 4.0 checks that value is a valid email address
IsDatetimeIsoFormat() 💛 4.0 checks that value is a datetime in ISO format. returns datetime instance
Datetime('%Y-%m-%d') 💛 4.0 #59
Number() 💛 4.1 #65
IntRule(), FloatRule(), BoolRule() 💛 4.3 #83
File(), FileChain() 💛 4.3 #85

Additional Information

Clone this wiki locally