Qval’s API¶
Auto-generated documentation of Qval’s code.
qval.qval¶
- class qval.qval.QueryParamValidator(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request], factories: Dict[str, Optional[type]], validators: Optional[Dict[str, Union[qval.validator.Validator, Callable[Any, bool]]]] = None, box_all: bool = True)[source]¶
Bases:
contextlib.AbstractContextManagerValidates query parameters.
- Examples:
>>> r = fwk.DummyRequest({"num": "42", "s": "str", "double": "3.14"}) >>> params = QueryParamValidator(r, dict(num=int, s=None, double=float)) >>> with params as p: ... print(p.num, p.s, p.double, sep=', ') 42, str, 3.14
- __enter__() → qval.utils.FrozenBox[source]¶
Runs validation on the provided request. See __exit__() for additional info.
- Returns
box of validated values.
- __exit__(exc_type, exc_val, exc_tb)[source]¶
If occurred exception is not an
InvalidQueryParamException, the exception will be re-raised as an APIException, which will result in the 500 error on the client side.- Parameters
exc_type – exception type
exc_val – exception instance
exc_tb – exception traceback
- Returns
None
- __init__(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request], factories: Dict[str, Optional[type]], validators: Optional[Dict[str, Union[qval.validator.Validator, Callable[Any, bool]]]] = None, box_all: bool = True)[source]¶
Instantiates the query validator.
- Parameters
request – fwk.Request instance
factories – a mapping of
{param -> factory}. ProvidingNoneas a factory is equivalent tostrorlambda x: x, since parameters are stored as strings.validators – a dictionary of pre-defined validators
box_all – include all params, even if they’re not specified in
factories
- add_predicate(param: str, predicate: Callable[Any, bool])[source]¶
Adds a new check for the provided parameter.
- Parameters
param – name of the request parameter
predicate – predicate function
- Returns
None
- apply_to_request(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request]) → qval.qval.QueryParamValidator[source]¶
Applies the current validation settings to a new request.
- Example:
>>> from qval.utils import make_request >>> request = make_request({"a": "77"}) >>> params = QueryParamValidator(request, {"a": int}, {"a": lambda x: x > 70}) >>> with params as p: ... print(p.a) # Prints 77 77 >>> with params.apply_to_request({"a": "10"}): pass # Error! Traceback (most recent call last): ... qval.exceptions.InvalidQueryParamException: ...
- Parameters
request – new request instance
- Returns
new
QueryParamValidatorinstance
- check(param: str, predicate: Callable[Any, bool]) → qval.qval.QueryParamValidator[source]¶
Adds a new check for the provided parameter.
- Parameters
param – name of the request parameter
predicate – predicate function
- Returns
self
- eq(param: str, value: Any, transform: Callable[Any, Any] = <function QueryParamValidator.<lambda>>) → qval.qval.QueryParamValidator[source]¶
Adds an equality check for the provided parameter. For example, if value = 10,
paramwill be tested as [transform(param) == 10].- Parameters
param – name of the request parameter
value – value to compare with
transform – callable that transforms the parameter, default:
lambda x: x
- Returns
self
- gt(param: str, value: Any, transform: Callable[Any, Any] = <function QueryParamValidator.<lambda>>) → qval.qval.QueryParamValidator[source]¶
Adds a
greater thancomparison check for provided parameter. For example, if value = 10,paramwill be tested as [transform(param) > 10].- Parameters
param – name of the request parameter
value – value to compare with
transform – callable that transforms the parameter, default:
lambda x: x
- Returns
self
- lt(param: str, value: Any, transform: Callable[Any, Any] = <function QueryParamValidator.<lambda>>) → qval.qval.QueryParamValidator[source]¶
Adds a less than comparison check for the provided parameter. For example, if value = 10,
paramwill be tested as [transform(param) < 10].- Parameters
param – name of the request parameter
value – value to compare with
transform – callable that transforms the parameter, default:
lambda x: x
- Returns
self
- nonzero(param: str, transform: Callable[Any, Any] = <function QueryParamValidator.<lambda>>) → qval.qval.QueryParamValidator[source]¶
Adds a nonzero check for the provided parameter. For example, if value = 10,
paramwill be tested as [transform(param) != 0].- Parameters
param – name of the request parameter
transform – callable that transforms the parameter, default:
lambda x: x
- Returns
self
- positive(param: str, transform: Callable[Any, Any] = <function QueryParamValidator.<lambda>>) → qval.qval.QueryParamValidator[source]¶
Adds a
greater than zerocomparison check for the provided parameter. Providedparamwill be tested as [transform(param) > 0].- Parameters
param – name of the request parameter
transform – callable that transforms the parameter, default:
lambda x: x
- Returns
self
- property query_params: Dict[str, str]¶
Returns the dictionary of the query parameters.
- qval.qval.qval(factories: Dict[str, Optional[Callable[str, Any]]], validators: Optional[Dict[str, Union[qval.validator.Validator, Callable[Any, bool]]]] = None, box_all: bool = True, request_: Optional[Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request]] = None)[source]¶
A decorator that validates query parameters. The wrapped function must accept a request as the first argument (or second if it’s a method), and params as last.
- Parameters
factories – a mapping (parameter, callable [str -> Any])
validators – a mapping (parameter, validator)
box_all – include all parameters in the output dictionary, even if they’re not specified in factories
request – optional request object that will always be provided to the validator
- Returns
wrapped function
- qval.qval.qval_curry(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request])[source]¶
Curries
qval()decorator and provides the givenrequestobject to the curried function on each call. This is especially handy in Flask, where request is global.Example: .. code-block:: python
>>> r = {"num": "42", "s": "str", "double": "3.14"} >>> qval = qval_curry(r) >>> @qval({"num": int, "double": float}, None) ... def view(request, extra_param, params): ... print(params.num, params.double, params.s, extra_param, sep=', ') >>> view("test") 42, 3.14, str, test
- Parameters
request – request instance
- Returns
wrapped
qval(..., request_=request)
- qval.qval.validate(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request], validators: Optional[Dict[str, Union[qval.validator.Validator, Callable[Any, bool]]]] = None, box_all: bool = True, **factories: Optional[Callable[str, Any]]) → qval.qval.QueryParamValidator[source]¶
Shortcut for QueryParamValidator.
- Examples:
>>> r = {"num": "42", "s": "str", "double": "3.14"} >>> with validate(r, num=int, s=None, double=float) as p: ... print(p.num + p.double, p.s) 45.14 str
>>> r = {"price": "43.5$", "n_items": "1"} >>> currency2f = lambda x: float(x[:-1]) >>> params = validate(r, price=currency2f, n_items=int ... ).positive("n_items") # n_items must be greater than 0 >>> with params as p: ... print(p.price, p.n_items) 43.5 1
- Parameters
request – a request object
validators – a dictionary of validators
box_all – include all parameters in the output dictionary, even if they’re not specified in factories
factories – a dictionary of callables that create a python object from their parameter
- Returns
QueryParamValidator instance
qval.validator¶
- exception qval.validator.QvalValidationError[source]¶
Bases:
ExceptionThe error raised if validation fails. This exception should be used to provide a custom validation error message to the client.
- Example:
>>> from qval import validate >>> def f(v: str) -> bool: ... if not v.isnumeric(): ... raise QvalValidationError(f"Expected a number, got '{v}'") ... return True >>> params = validate({"number": "42"}, {"number": f}) >>> with params: pass # OK >>> with params.apply_to_request({"number": "a string"}): pass Traceback (most recent call last): ... qval.exceptions.InvalidQueryParamException: ...
- class qval.validator.Validator(*predicates: Union[qval.validator.Validator, Callable[Any, bool]])[source]¶
Bases:
objectValidates the given value using the provided predicates.
- __call__(value: Any) → bool[source]¶
Applies all stored predicates to the given value.
- Parameters
value – value to validate
- Returns
True if all checks have passed, False otherwise
- Predicate = typing.Union[_ForwardRef('Validator'), typing.Callable[[typing.Any], bool]]¶
- ValidatorType = typing.Union[_ForwardRef('Validator'), typing.Callable[[typing.Any], bool]]¶
- __init__(*predicates: Union[qval.validator.Validator, Callable[Any, bool]])[source]¶
Instantiates the validator.
- Parameters
predicates (Callable[[Any], bool]) – predefined predicates
- add(predicate: Union[qval.validator.Validator, Callable[Any, bool]]) → qval.validator.Validator[source]¶
Adds the predicate to the list.
- Parameters
predicate – predicate function
- Returns
self
qval.exceptions¶
qval.utils¶
- class qval.utils.ExcLogger[source]¶
Bases:
objectA class used to report critical errors.
>>> from qval.utils import log >>> log ExcLogger() >>> log.is_enabled True >>> log.disable() >>> print(log) ExcLogger<<Logger qval (WARNING)>>, enabled = false>
- error(*args, **kwargs)[source]¶
A shortcut for
log("error", ...).- Parameters
args – log args
kwargs – log kwargs
- Returns
None
- property is_enabled: bool¶
Returns True if logging is enabled.
- class qval.utils.FrozenBox(dct: Dict[Any, Any])[source]¶
Bases:
objectA frozen dictionary that allows accessing its elements with
.- Example:
>>> box = FrozenBox({"num": 10, "s": "string"}) >>> print(box.num, box.s) 10 string >>> box["num"] = 404 Traceback (most recent call last): ... TypeError: 'FrozenBox' object does not support item assignment >>> box.num = 404 Traceback (most recent call last): ... TypeError: 'FrozenBox' object does not support attribute assignment >>> box.num 10
- qval.utils.dummify(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request]) → qval.framework_integration.DummyRequest[source]¶
Constructs a
qval.framework_integration.DummyRequestwith the parameters in the given request.- Parameters
request – any supported request
- Returns
DummyRequest(request.<params>)
- qval.utils.get_request_params(request: (<class 'dict'>, <class 'qval.framework_integration.DummyRequest'>, <class 'rest_framework.request.Request'>, <class 'django.http.request.HttpRequest'>, <class 'flask.wrappers.Request'>, <class 'falcon.request.Request'>))[source]¶
Returns a dictionary of the query parameters in the given request.
- Parameters
request – any supported request
- Returns
dictionary of parameters
- qval.utils.make_request(request: Union[dict, qval.framework_integration.DummyRequest, rest_framework.request.Request, django.http.request.HttpRequest, flask.wrappers.Request, falcon.request.Request]) -> (<class 'dict'>, <class 'qval.framework_integration.DummyRequest'>, <class 'rest_framework.request.Request'>, <class 'django.http.request.HttpRequest'>, <class 'flask.wrappers.Request'>, <class 'falcon.request.Request'>)[source]¶
Creates a
qval.framework_integration.DummyRequestifrequestis a dictionary, and returns therequestitself otherwise.The behavior of this function can be customized with the
@_make_request()decorator. Provide the path to your wrapper usingQVAL_MAKE_REQUEST_WRAPPERin the settings file or set it as an environment variable. The wrapper function must acceptrequestas its first argument and return an object that implements the request interface.For example, the following code adds print each incoming request:
# settings.py QVAL_MAKE_REQUEST_WRAPPER = "app.utils.my_wrapper" # app/utils.py def my_wrapper(f): @functools.wraps(f) def wrapper(request): print(f"Received new request: {request}") return f(request) return wrapper
- Parameters
request – dict or request instance
- Returns
request
qval.framework_integration¶
- class qval.framework_integration.DummyRequest(params: Dict[str, str])[source]¶
Bases:
objectDummyRequest. Used for compatibility with the supported frameworks.
- __init__(params: Dict[str, str])[source]¶
Initialize self. See help(type(self)) for accurate signature.
- property query_params: Dict[str, str]¶
More semantically correct name for request.GET.
- qval.framework_integration.get_module() → Union[qval.framework_integration._EnvironSettings, Module][source]¶
Attempts to load the settings module. If none of the supported env variables are defined, returns
_EnvironSettings()object.
- qval.framework_integration.load_symbol(path: object)[source]¶
Imports an object using the given path.
- Parameters
path – path to an object, e.g. my.module.func_1
- Returns
loaded symbol
- qval.framework_integration.setup_django_middleware(module: Module = None)[source]¶
Setups the exception-handling middleware.
- Parameters
module – settings module
- Returns
None