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.AbstractContextManager
Validates 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}
. ProvidingNone
as a factory is equivalent tostr
orlambda 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
QueryParamValidator
instance
- 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,
param
will 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 than
comparison check for provided parameter. For example, if value = 10,param
will 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,
param
will 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,
param
will 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 zero
comparison check for the provided parameter. Providedparam
will 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 givenrequest
object 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:
Exception
The 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:
object
Validates 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:
object
A 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:
object
A 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.DummyRequest
with 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.DummyRequest
ifrequest
is a dictionary, and returns therequest
itself otherwise.The behavior of this function can be customized with the
@_make_request()
decorator. Provide the path to your wrapper usingQVAL_MAKE_REQUEST_WRAPPER
in the settings file or set it as an environment variable. The wrapper function must acceptrequest
as 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:
object
DummyRequest. 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