infoxtractor/src/ix/use_cases/__init__.py
Dirk Riemann b80c7952f7
All checks were successful
tests / test (pull_request) Successful in 1m0s
tests / test (push) Successful in 58s
feat(use_cases): registry + bank_statement_header (spec §7)
First use case lands. The schema is intentionally flat — nine scalar fields,
no nested arrays — because Ollama's structured-output guidance stays most
reliable when the top level has only scalars, and every field we care about
(bank_name, IBAN, period, opening/closing balance) can be rendered as one.

Registration is explicit in `use_cases/__init__.py`, not a side effect of
importing the use-case module. That keeps load order obvious and lets tests
patch the registry without having to reload modules.

`get_use_case(name)` is the one-liner adapters use; it raises
`IX_001_001` with the offending name in `detail` when the lookup misses,
which keeps log-scrape simple.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 10:51:43 +02:00

41 lines
1.4 KiB
Python

"""Use-case registry.
Adding a use case is a two-line change:
1. Write ``ix/use_cases/<name>.py`` exporting
``Request(BaseModel)`` (with ``use_case_name``, ``default_model``,
``system_prompt``) and ``<Response>(BaseModel)`` with the extraction
schema.
2. Add ``"<name>": (Request, <Response>)`` to :data:`REGISTRY` below.
No import-time side effects in use-case modules — registration is explicit
so the load order is obvious and tests can patch the registry cleanly.
"""
from __future__ import annotations
from pydantic import BaseModel
from ix.errors import IXErrorCode, IXException
from ix.use_cases.bank_statement_header import BankStatementHeader
from ix.use_cases.bank_statement_header import Request as BankStatementHeaderRequest
REGISTRY: dict[str, tuple[type[BaseModel], type[BaseModel]]] = {
"bank_statement_header": (BankStatementHeaderRequest, BankStatementHeader),
}
def get_use_case(name: str) -> tuple[type[BaseModel], type[BaseModel]]:
"""Look up a registered use case by name.
Raises :class:`IXException` with :attr:`IXErrorCode.IX_001_001` when the
name is not in the registry — the offending name is embedded in the
``detail`` for log-scrape.
"""
try:
return REGISTRY[name]
except KeyError as exc:
raise IXException(IXErrorCode.IX_001_001, detail=name) from exc
__all__ = ["REGISTRY", "get_use_case"]