From 735c78d3ecb695dd16cb37879880f522c4b29c72 Mon Sep 17 00:00:00 2001 From: Johan Fleury Date: Mon, 8 Oct 2018 12:58:12 -0400 Subject: Import upstream version 1.7.0 --- docs/extensions.rst | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 docs/extensions.rst (limited to 'docs/extensions.rst') diff --git a/docs/extensions.rst b/docs/extensions.rst new file mode 100644 index 0000000..24dee64 --- /dev/null +++ b/docs/extensions.rst @@ -0,0 +1,105 @@ +Extensions +========== + +It is possible to extend the validation of each of the three basic types, ``map`` & ``seq`` & ``scalar``. + +Extensions can be used to do more complex validation that is not natively supported by the core pykwalify lib. + + + +Loading extensions +------------------ + +There are 2 ways to load extensions into a schema. + +First you can specify any ``*.py`` file via the cli via the ``-e FILE`` or ``--extension FILE`` flag. If you would do this when using pykwalify as a library you should pass in a list of files to the ``extensions`` variable to the ``Core`` class. + +The second way is to specify a list of files in the keyword ``extensions`` that can only be specified at the top level of the schema. The files can be either relative or absolute. + + + +How custom validation works +--------------------------- + +Each function defined inside the extension must be defined with a globally unique method name and the following variables + +.. code-block:: python + + def method_name(value, rule_obj, path): + pass + +To raise a validation error you can either raise any exception and it will propegate up to the caller or you can return ``True`` or ``False``. Any value/object that will be interpreted as ``False`` inside a if check will cause a ``CoreError`` validation error to be raised. + +When using a validation function on a ``sequence``, the method will be called with the entire list content as the value. + +When using a validation function on a ``mapping``, the method will be called with the entire dict content as the value. + +When using a validation function on any ``scalar`` type value, the method will be called with the scalar value. + +This is a example of how to use extensions inside a simple schema + +.. code-block:: yaml + + # Schema + extensions: + - e.py + type: map + func: ext_map + mapping: + foo: + type: seq + func: ext_list + sequence: + - type: str + func: ext_str + +.. code-block:: yaml + + # Data + foo: + - foo + - bar + +This is the extension file named ``ext.py`` that is located in the same directory as the schema file. + +.. code-block:: python + + # -*- coding: utf-8 -*- + import logging + log = logging.getLogger(__name__) + + + def ext_str(value, rule_obj, path): + log.debug("value: %s", value) + log.debug("rule_obj: %s", rule_obj) + log.debug("path: %s", path) + + # Either raise some exception that you have defined your self + # raise AssertionError('Custom assertion error in jinja_function()') + + # Or you should return True/False that will tell if it validated + return True + + + def ext_list(value, rule_obj, path): + log.debug("value: %s", value) + log.debug("rule_obj: %s", rule_obj) + log.debug("path: %s", path) + + # Either raise some exception that you have defined your self + # raise AssertionError('Custom assertion error in jinja_function()') + + # Or you should return True/False that will tell if it validated + return True + + + def ext_map(value, rule_obj, path): + log.debug("value: %s", value) + log.debug("rule_obj: %s", rule_obj) + log.debug("path: %s", path) + + # Either raise some exception that you have defined your self + # raise AssertionError('Custom assertion error in jinja_function()') + + # Or you should return True/False that will tell if it validated + return True -- cgit v1.2.3