examples.29_records_validation
Validate a list of small records (dicts) where each field is checked using
constrained value types such as RangeValue and EnumValue.
This example shows:
- How to iterate over a list of input records and validate each field.
- How to collect normalized/typed outputs for valid rows.
- How to collect structured error information for invalid rows.
Run directly:
python examples/29_records_validation.py
Expected output:
OK: [{'id': 1, 'role': 'user'}, {'id': 2, 'role': 'admin'}] ERRS: [(1, "Value must be one of 'int', got 'str'", "Value must be one of ('user', 'admin'), got owner")]
1"""Validate a list of small records (dicts) where each field is checked using 2constrained value types such as :class:`RangeValue` and :class:`EnumValue`. 3 4This example shows: 5 * How to iterate over a list of input records and validate each field. 6 * How to collect normalized/typed outputs for valid rows. 7 * How to collect structured error information for invalid rows. 8 9Run directly: 10 11 python examples/29_records_validation.py 12 13Expected output: 14 15 OK: [{'id': 1, 'role': 'user'}, {'id': 2, 'role': 'admin'}] 16 ERRS: [(1, "Value must be one of 'int', got 'str'", "Value must be one of ('user', 'admin'), got owner")] 17""" 18 19import sys 20import pathlib 21from enum import Enum 22from typing import List, Dict, Any, Tuple 23 24# --------------------------------------------------------------------------- 25# Make repo root importable when running this file directly 26# --------------------------------------------------------------------------- 27sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1])) 28 29from constrained_values import RangeValue, EnumValue, Status 30 31 32class Role(Enum): 33 """Valid roles for records.""" 34 USER = "user" 35 ADMIN = "admin" 36 37 38def validate_records(rows: List[Dict[str, Any]]) -> Tuple[List[Dict[str, Any]], List[Tuple[int, Any, Any]]]: 39 """Validate a list of record dicts. 40 41 Each row is expected to contain: 42 * ``id`` — an integer in the inclusive range ``[1, 10**9]``. 43 * ``role`` — one of :class:`Role` (``"user"`` or ``"admin"``), accepted 44 either as the enum member or its underlying string value. 45 46 For each row: 47 * If both fields validate, a normalized dict ``{"id": int, "role": Role}`` 48 is appended to the OK list. 49 * Otherwise, an error tuple ``(index, id_error, role_error)`` is appended 50 to the error list. Missing errors are reported as ``None``. 51 52 Args: 53 rows: Input records to validate. 54 55 Returns: 56 Tuple[List[Dict[str, Any]], List[Tuple[int, Any, Any]]]: 57 * First item — list of normalized, valid rows. 58 * Second item — list of error tuples with the original row index and 59 per-field error messages (or ``None`` if that field was OK). 60 """ 61 out: List[Dict[str, Any]] = [] 62 errs: List[Tuple[int, Any, Any]] = [] 63 64 for i, row in enumerate(rows): 65 uid = RangeValue(row.get("id"), 1, 10 ** 9) 66 role = EnumValue(row.get("role"), Role) 67 68 if uid.status == Status.OK and role.status == Status.OK: 69 out.append({"id": uid.value, "role": role.value}) 70 else: 71 errs.append( 72 ( 73 i, 74 uid.details if uid.status != Status.OK else None, 75 role.details if role.status != Status.OK else None, 76 ) 77 ) 78 79 return out, errs 80 81 82def main() -> None: 83 """Run the record list validation demonstration. 84 85 Creates a list with two valid rows and one invalid row, validates them, 86 then prints the OK results and the collected error details. 87 88 Prints: 89 * ``OK: [...]`` — normalized rows. 90 * ``ERRS: [...]`` — list of (index, id_error, role_error). 91 """ 92 rows = [ 93 {"id": 1, "role": "user"}, 94 {"id": "x", "role": "owner"}, 95 {"id": 2, "role": Role.ADMIN}, 96 ] 97 98 ok, bad = validate_records(rows) 99 print("OK:", ok) 100 print("ERRS:", bad) 101 102 103if __name__ == "__main__": 104 main()
Valid roles for records.
Inherited Members
- enum.Enum
- name
- value
39def validate_records(rows: List[Dict[str, Any]]) -> Tuple[List[Dict[str, Any]], List[Tuple[int, Any, Any]]]: 40 """Validate a list of record dicts. 41 42 Each row is expected to contain: 43 * ``id`` — an integer in the inclusive range ``[1, 10**9]``. 44 * ``role`` — one of :class:`Role` (``"user"`` or ``"admin"``), accepted 45 either as the enum member or its underlying string value. 46 47 For each row: 48 * If both fields validate, a normalized dict ``{"id": int, "role": Role}`` 49 is appended to the OK list. 50 * Otherwise, an error tuple ``(index, id_error, role_error)`` is appended 51 to the error list. Missing errors are reported as ``None``. 52 53 Args: 54 rows: Input records to validate. 55 56 Returns: 57 Tuple[List[Dict[str, Any]], List[Tuple[int, Any, Any]]]: 58 * First item — list of normalized, valid rows. 59 * Second item — list of error tuples with the original row index and 60 per-field error messages (or ``None`` if that field was OK). 61 """ 62 out: List[Dict[str, Any]] = [] 63 errs: List[Tuple[int, Any, Any]] = [] 64 65 for i, row in enumerate(rows): 66 uid = RangeValue(row.get("id"), 1, 10 ** 9) 67 role = EnumValue(row.get("role"), Role) 68 69 if uid.status == Status.OK and role.status == Status.OK: 70 out.append({"id": uid.value, "role": role.value}) 71 else: 72 errs.append( 73 ( 74 i, 75 uid.details if uid.status != Status.OK else None, 76 role.details if role.status != Status.OK else None, 77 ) 78 ) 79 80 return out, errs
Validate a list of record dicts.
Each row is expected to contain:
id— an integer in the inclusive range[1, 10**9].role— one ofRole("user"or"admin"), accepted either as the enum member or its underlying string value.
For each row:
- If both fields validate, a normalized dict
{"id": int, "role": Role}is appended to the OK list.- Otherwise, an error tuple
(index, id_error, role_error)is appended to the error list. Missing errors are reported asNone.
Arguments:
- rows: Input records to validate.
Returns:
Tuple[List[Dict[str, Any]], List[Tuple[int, Any, Any]]]: * First item — list of normalized, valid rows. * Second item — list of error tuples with the original row index and per-field error messages (or
Noneif that field was OK).
83def main() -> None: 84 """Run the record list validation demonstration. 85 86 Creates a list with two valid rows and one invalid row, validates them, 87 then prints the OK results and the collected error details. 88 89 Prints: 90 * ``OK: [...]`` — normalized rows. 91 * ``ERRS: [...]`` — list of (index, id_error, role_error). 92 """ 93 rows = [ 94 {"id": 1, "role": "user"}, 95 {"id": "x", "role": "owner"}, 96 {"id": 2, "role": Role.ADMIN}, 97 ] 98 99 ok, bad = validate_records(rows) 100 print("OK:", ok) 101 print("ERRS:", bad)
Run the record list validation demonstration.
Creates a list with two valid rows and one invalid row, validates them, then prints the OK results and the collected error details.
Prints:
OK: [...]— normalized rows.ERRS: [...]— list of (index, id_error, role_error).