ProvenPin Install

Cerberus schemas: coercion, defaults and custom rules: working versions (tested 2026-10-16)

A Cerberus signup schema that coerces types, fills default and default_setter fields, and enforces subclass plus check_with rules, tested offline.

passed5 passed · 0 failed2026-10-16 09:57 UTC
Status
passed
Last passed
2026-10-16 09:57 UTC
Tests
5 / 5
Language
Python
Runtime
Python 3.13.16
pinned versions2
cerberus@1.3.8pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 38883899161

The code

Exactly the files that passed. Your agent can pull them with get_recipe("cerberus-schema-normalization") (install), or see them on GitHub.

requirements.txt
cerberus==1.3.8
pytest==9.1.1
schema.py
from cerberus import Validator


def default_nickname(doc):
    return doc["username"].split("@")[0].strip()


def strong_password(field, value, error):
    if not any(c.isdigit() for c in value):
        error(field, "must contain a digit")


SIGNUP = {
    "username": {
        "type": "string",
        "coerce": str.strip,
        "required": True,
        "empty": False,
        "is_lower": True,
    },
    "email": {
        "type": "string",
        "required": True,
        "regex": r"^[^@\s]+@[^@\s]+\.[^@\s]+$",
    },
    "age": {"type": "integer", "coerce": int, "min": 13},
    "password": {"type": "string", "required": True, "check_with": strong_password},
    "role": {"type": "string", "default": "viewer", "allowed": ["viewer", "editor"]},
    "tags": {
        "type": "list",
        "default": [],
        "schema": {"type": "string", "coerce": str.lower},
    },
    "nickname": {"type": "string", "default_setter": default_nickname},
}


class SignupValidator(Validator):
    def _validate_is_lower(self, is_lower, field, value):
        """{'type': 'boolean'}"""
        if is_lower and value != value.lower():
            self._error(field, "must be lowercase")
tests/test_schema.py
from schema import SIGNUP, SignupValidator

BASE = {
    "username": "ada",
    "email": "[email protected]",
    "age": "36",
    "password": "s3cret",
}


def test_validated_coerces_and_applies_defaults():
    v = SignupValidator(SIGNUP)
    doc = v.validated({**BASE, "tags": ["Math", "LOGIC"]})
    assert v.errors == {}
    assert doc["age"] == 36
    assert doc["role"] == "viewer"
    assert doc["tags"] == ["math", "logic"]
    assert doc["nickname"] == "ada"


def test_normalized_skips_validation_rules():
    v = SignupValidator(SIGNUP)
    out = v.normalized({**BASE, "username": "Ada"})
    assert out["username"] == "Ada" and v.errors == {}
    assert v.validated({**BASE, "username": "Ada"}) is None
    assert v.errors["username"] == ["must be lowercase"]


def test_default_overrides_none_unless_nullable():
    plain = SignupValidator({"role": {"type": "string", "default": "viewer"}})
    assert plain.normalized({})["role"] == "viewer"
    assert plain.normalized({"role": None})["role"] == "viewer"
    nullable = SignupValidator(
        {"role": {"type": "string", "default": "viewer", "nullable": True}}
    )
    assert nullable.normalized({"role": None})["role"] is None


def test_purge_unknown_vs_unknown_rejected():
    loose = SignupValidator(SIGNUP, purge_unknown=True)
    assert "admin" not in loose.normalized({**BASE, "admin": True})
    strict = SignupValidator(SIGNUP)
    assert strict.validate({**BASE, "age": 36, "admin": True}) is False
    assert strict.errors["admin"] == ["unknown field"]


def test_check_with_password_rule():
    v = SignupValidator(SIGNUP)
    assert v.validate({**BASE, "age": 36, "password": "nodigits"}) is False
    assert v.errors["password"] == ["must contain a digit"]
pytest.ini
[pytest]
pythonpath = .

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.