spb/air Public MIT
AIR — The Language of Accounting.
Python 100%
1# =============================================================================2# Projet : AIR — Accounting Intermediate Representation3# Auteur : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : document_io.py6# Description : Load/serialize AIR documents (YAML/JSON) with strict float rejection.7# =============================================================================8"""AIR document I/O.910AIR documents are YAML or JSON. All amounts, quantities, and rates MUST be11strings ("19.99") — bare numbers would arrive as binary floats and are12rejected by the schema (see core/events.py). This keeps every figure exact.13"""14from __future__ import annotations1516import json17from pathlib import Path18from typing import Any1920import yaml2122from core.events import AirDocument232425def load_air_document(path: str | Path) -> AirDocument:26 path = Path(path)27 text = path.read_text(encoding="utf-8")28 data: Any29 if path.suffix == ".json":30 data = json.loads(text)31 data.pop("_author", None) # header key, not part of the schema32 else:33 data = yaml.safe_load(text)34 if not isinstance(data, dict):35 raise ValueError(f"{path}: expected a mapping at top level")36 return AirDocument.model_validate(data)373839def dump_air_document(document: AirDocument) -> str:40 """Canonical JSON serialization (amounts as strings)."""41 payload = {"_author": "Simon-Pierre Boucher <contact@spboucher.ai>"}42 payload.update(json.loads(document.model_dump_json(exclude_none=True)))43 return json.dumps(payload, indent=2, default=str)44