# Flask Parameter Validation
### Get and validate all Flask input parameters with ease.
## Install
* Pip: Install with `pip install flask_parameter_validation`.
* Manually:
- `git clone https://github.com/Ge0rg3/flask-parameter-validation.git`
- `python setup.py install`
## Simple Usage
```py
from flask import Flask
from typing import List, Optional
from flask_parameter_validation import ValidateParameters, Route, Json, Query
from datetime import datetime
app = Flask(__name__)
@app.route("/update/<int:id>", methods=["POST"])
@ValidateParameters()
def hello(
id: int = Route(),
username: str = Json(min_str_length=5, blacklist="<>"),
age: int = Json(min_int=18, max_int=99),
nicknames: List[str] = Json(),
date_of_birth: datetime = Json(),
password_expiry: Optional[int] = Json(5),
is_admin: bool = Query(False)
):
return "Hello World!"
if __name__ == "__main__":
app.run()
```
## Detailed Usage
1. We use the ValidateParameters decorator on all functions that this modules should be used in.
2. The format for arguments is as follows:
`parameter_name: parameter_type = Class()`
In this example, `parameter_name` would be the field name itself, such as "username". `parameter_type` would be the expected python data type, such as str, int, List, Union etc. Finally, `Class()` is one of the class inputs, as detailed below:
### Classes
1. Route()
This is the data passed through the URL, such as `/users/<int:id>`
2. Form()
This is the data passed by a normal HTML form, often with x-www-form-urlencoded content-type.
3. Json()
This is any JSON body sent -- request must have application/json content type for flask to read this.
4. Query()
This covers query parameters (aka GET parameters), such as `/news/article?id=55`
5. File()
The validation on files are different to the others, but file input can still be obtained here as their Flask FileStorage objects.
### Input types
* str
* int
* bool
* float
* typing.List
* typing.Union
* typing.Optional
* datetime.datetime
### Validation
All parameters can have default values, and automatic validation.
`Route`, `Form`, `Json` and `Query` have the following options:
* default: any, Specifies the default value for the field.
* min_str_length: int, Specifies the minimum character length for a string input
* max_str_length: int, Specifies the maximum character length for a string input
* min_list_length: int, Specifies the minimum number of elements in a list
* max_list_length: int, Specifies the maximum number of elements in a list
* min_int: int, Specifies the minimum number for an int input
* max_int: int, Specifies the maximum number for an int input
* whitelist: str, A string containing allowed characters for the value
* blacklist: str, A string containing forbidden characters for the value
* pattern: str, A regex pattern to test for string matches
* func: Callable, A function containing a fully customized logic to validate the value
`File` has the following options:
* content_types: array of strings, an array of allowed content types.
* min_length: Minimum content-length for a file
* max_length: Maximum content-length for a file
These validators are passed into the classes in the route function, such as:
* `username: str = Json("defaultusername", min_length=5)`
* `profile_picture: Any = File(content_types=["image/png", "image/jpeg"])`
* `filter: str = Query()`
### Overwriting default errors
By default, the error messages are returned as a JSON response, with the detailed error in the "error" field. However, this can be edited by passing a custom error function into the ValidateParameters decorator. For example:
```py
def error_handler(err):
error_name = type(err)
error_parameters = err.args
error_message = str(err)
return {
"error_name": type(err).__name__,
"error_parameters": err.args,
"error_message": str(err)
}, 400
@ValidateParameters(error_handler)
def api(...)
```