Welcome to Validobj’s documentation!

Validobj is a library that processes semistructured input coming from sources a JSON mapping or a YAML configuration file into more structured Python objects. The main API function, validobj.validation.parse_input(), takes care of that

import dataclasses
import enum
from typing import Literal

from validobj import parse_input

inp = {
    'global_environment': {'CI_ACTIVE': '1'},
    'stages': [
        {
            'name': 'compile',
            'os': ['linux', 'mac'],
            'script_path': 'build.sh',
            'disk_permissions': ['READ', 'WRITE', 'EXECUTE'],
        },
        {
            'name': 'test',
            'os': ['linux', 'mac'],
            'script_path': 'test.sh',
            'framework_version': [4, 0],
        },
    ],
}


class DiskPermissions(enum.Flag):
    READ = enum.auto()
    WRITE = enum.auto()
    EXECUTE = enum.auto()



@dataclasses.dataclass
class Job:
    name: str
    os: set[Literal['windows', 'mac', 'linux']]
    script_path: str
    framework_version: tuple[int, int] = (1, 0)
    disk_permissions: DiskPermissions = DiskPermissions.READ


@dataclasses.dataclass
class CIConf:
    stages: list[Job]
    global_environment: dict[str, str] = dataclasses.field(default_factory=dict)



print(parse_input(inp, CIConf))
# This results in a dataclass instance with the correct types:
#
#CIConf(
#    stages=[
#        Job(
#            name='compile',
#            os={'linux', 'mac'},
#            script_path='build.sh',
#            framework_version=(1, 0),
#            disk_permissions=<DiskPermissions.EXECUTE|WRITE|READ: 7>,
#        ),
#        Job(
#            name='test',
#            os={'linux', 'mac'},
#            script_path='test.sh',
#            framework_version=(4, 0),
#            disk_permissions='<DiskPermissions.READ: 1>',
#        ),
#    ],
#    global_environment={'CI_ACTIVE': '1'},
#)
#

The full set of applied checks and transformations is described in Input and output.

Validobj aims at providing building blocks to construct the most human friendly error handling in town. Its exceptions provide lots of information on what went wrong as well as good messages, which even contain suggestions on typos.

>>> import enum
>>> import validobj
>>> class DiskPermissions(enum.Flag):
...     READ = enum.auto()
...     WRITE = enum.auto()
...     EXECUTE = enum.auto()
...
>>> validobj.parse_input(['EXECUTE', 'RAED'], DiskPermissions) 
NotAnEnumItemError                        Traceback (most recent call last)
...
NotAnEnumItemError: 'RAED' is not a valid member of 'DiskPermissions'.
Alternatives to invalid value 'RAED' include:
  - READ
All valid values are:
  - READ
  - WRITE
  - EXECUTE

The above exception was the direct cause of the following exception:
...
WrongListItemError: Cannot process item 2 into 'DiskPermissions'.

When more control is needed, Validobj allows passing custom functions to handle transformations.

A limited subset of the parsing facilities work with Python 3.8, which is the minimum version. The custom validation module requires at least Python 3.9.

The superseded functionality in PEP 563 – Postponed Evaluation of Annotations is not supported.

Indices and tables