Skip to content

Examples

Danila Ganchar edited this page Jan 5, 2024 · 11 revisions

Headers validation

Headers validation works first. All other parameters will processed only after successful validation of headers. Example:

@app.route('/headers')
@validate_params(
    Param('Accept-Language', HEADER, str, rules=[Enum('en-US', 'be-BE')])
)
def headers(valid: ValidRequest):
    return jsonify(valid.get_headers())
Input Output
curl http://localhost:5000/headers 🔴 ["invalid header Accept-Language. value is required"]
curl -H 'Accept-Language: test' http://localhost:5000/headers 🔴 ["invalid header Accept-Language. not allowed, allowed values: en-US|be-BE"]
curl -H 'Accept-Language: be-BE' http://localhost:5000/headers 🟢 {"Accept-Language": "be-BE"}

Custom validation Rule

In some cases we need to use complex logic or third-party services for validation. You can create a custom validation rule in such cases:

class CountryCodeRule(AbstractRule):
    def validate(self, value: str) -> str:
        # do here all what you need...
        data = requests.get(f'https://restcountries.com/v3.1/alpha/{value}').json()
        if isinstance(data, list) and len(data) > 0:
            # correct value
            return value

        raise RuleError(f'invalid country code: {value}')


@app.route('/country/<string:country_code>')
@validate_params(
    Param('country_code', PATH, str, rules=[CountryCodeRule()]),
)
def country(valid: ValidRequest, country_code):
    return jsonify(country_code=country_code)

Request / Response examples:

curl http://localhost:5000/country/by  # {"country_code": "by"}
curl http://localhost:5000/country/unknown_country_code
# [
#  {
#    "errors": {
#      "country_code": "invalid country code: unknown_country_code"
#    },
#    "message": "invalid PATH parameters"
#  }
# ]

AfterParam hook

In some cases we need additional processing only after all types and values are correct. You can create a custom AfterParam in such cases:

class VersionAfterParam(AbstractAfterParam):
    def validate(self, value: ValidRequest) -> Any:
        # do here all what you need...
        data = value.get_json()
        if 'some_flag' in data and int(data['version'][1:]) < 99:
            raise AfterParamError('some_flag is only supported starting from version 99')
        return value

@app.route('/version', methods=['POST'])
@validate_params(
    Param('some_flag', JSON, str, required=False),
    Param('version', JSON, str, rules=[Enum('v1', 'v2', 'v99')]),
    VersionAfterParam(),
)
def version(valid: ValidRequest):
    return jsonify(version=valid.get_json().get('some_flag'))

Request / Response examples:

curl -H 'Content-Type: application/json' -d '{"version": "v1", "some_flag": "test"}' http://localhost:5000/version
# ["some_flag is only supported starting from version 99"]

curl -H 'Content-Type: application/json' -d '{"version": "v99", "some_flag": "test"}' http://localhost:5000/version 
# {"version": "test"}
Clone this wiki locally