Picarones / docs /reference /api-stable.md
Claude
docs: Phase 2 — vérité documentaire (compteurs, fantômes, legacy refs)
2c2bc0f unverified

API publique stable de Picarones

Statut v2.0 (mai 2026) : la migration vers l'architecture 8 couches canoniques est terminée. Tous les paquets legacy top-level (picarones.core, picarones.measurements, picarones.engines, picarones.modules, picarones.report, picarones.llm, picarones.pipelines, picarones.cli, picarones.web, picarones.extras) ainsi que les sous-paquets transitoires (adapters/legacy_engines/, adapters/legacy_pipelines/, interfaces/{cli,web}/_legacy/) ont été supprimés. Plus aucun shim, plus aucun DeprecationWarning rétrocompat.

Architecture canonique (cf. docs/explanation/architecture.md) : domain → formats → evaluation → pipeline → adapters → app → reports → interfaces.

Chantier post-rewrite (mai 2026, branche claude/fix-module-rewiring-MHssX) : réconciliation des contrats UI/API/runner après la migration. Ruptures API visibles côté consommateur :

  • CompetitorConfigPipelineConfig.
  • PipelineConfig.ocr_enginePipelineConfig.engine_name (le field accepte aussi corpus et des VLMs zero-shot — le préfixe ocr_ était trompeur).
  • PipelineConfig.pipeline_mode typé Literal["text_only", "text_and_image", "zero_shot"] ; toute autre valeur (y compris les anciens alias post_correction_text / post_correction_image) est rejetée en 422.

Définition

L'API publique stable de Picarones est constituée des classes, fonctions, constantes et types listés ci-dessous, exportés depuis l'arborescence canonique 8 couches.

Ce qui n'est pas dans cette liste peut évoluer à tout moment sans bump majeur — utiliser ces points d'entrée pour une intégration durable.

Test automatique

Le test tests/test_public_api.py vérifie que tous les noms listés ici existent et restent accessibles. Il échoue si un nom disparaît ou change de forme.

Liste exhaustive

picarones.evaluation.corpus

class GTLevel(str, Enum):
    TEXT, ALTO, PAGE, ENTITIES, READING_ORDER

class TextGT:           # GT texte plat
class AltoGT:           # GT ALTO XML
class PageGT:           # GT PAGE XML
class EntitiesGT:       # GT entités nommées (NER)
class ReadingOrderGT:   # GT ordre de lecture des régions
GTPayload = Union[...]  # type alias

class Document:         # un document du corpus (image + GT multi-niveaux)
class Corpus:           # collection de Documents

GT_SUFFIXES: dict[GTLevel, str]   # mapping niveau → suffixe fichier

def load_corpus_from_directory(path) -> Corpus

picarones.domain.artifacts

class ArtifactType(str, Enum):
    IMAGE, RAW_TEXT, CORRECTED_TEXT, ALTO_XML, PAGE_XML,
    CANONICAL_DOCUMENT, ENTITIES, READING_ORDER, ALIGNMENT, CONFIDENCES
    # Aliases legacy pour rétrocompat : TEXT, ALTO, PAGE

picarones.domain.module_protocol

class BaseModule(ABC):
    input_types: tuple[ArtifactType, ...]
    output_types: tuple[ArtifactType, ...]
    execution_mode: "io" | "cpu"

    @property name
    @abstractmethod process(inputs)
    metadata() -> dict
    validate_inputs(inputs)
    validate_outputs(outputs)

ExecutionMode = Literal["io", "cpu"]

picarones.evaluation.benchmark_result

class DocumentResult:    # résultat moteur sur un doc (CER, métriques, taxonomy…)
class EngineReport:      # agrégat moteur sur tout le corpus
class BenchmarkResult:   # résultat global multi-moteurs

picarones.evaluation.metrics.text_metrics

class MetricsResult:     # CER, WER, MER, WIL + variantes diplomatique/caseless
def compute_metrics(reference, hypothesis, char_exclude=None) -> MetricsResult
def aggregate_metrics(results: list) -> dict

picarones.app.services.benchmark_runner

def run_benchmark_via_service(
    corpus, engines,
    output_json=None,
    show_progress=True,
    progress_callback=None,
    char_exclude=None,
    max_workers=4,
    timeout_seconds=60.0,
    partial_dir=None,
    cancel_event=None,
    entity_extractor=None,
    profile="standard",
    normalization_profile=None,
) -> BenchmarkResult

Sprint D du plan v2.0 — adapter de compatibilité qui présente l'API mono-call historique de measurements.runner.run_benchmark (supprimé en D.6.b) en s'appuyant en interne sur BenchmarkService (rewrite). Prouvé numériquement équivalent en D.1.e.

picarones.evaluation.metric_registry

class MetricSpec:    # frozen dataclass : name, func, input_types, ...

def register_metric(*, name, input_types, ...) -> Callable
def get_metric(name) -> MetricSpec
def all_metrics() -> list[MetricSpec]
def select_metrics(input_types) -> list[MetricSpec]
def compute_at_junction(reference, hypothesis, input_types, *, skip_on_error=True) -> dict

picarones.evaluation.metric_hooks

# Profils — constantes
PROFILE_MINIMAL = "minimal"
PROFILE_STANDARD = "standard"
PROFILE_PHILOLOGICAL = "philological"
PROFILE_DIAGNOSTICS = "diagnostics"
PROFILE_ECONOMICS = "economics"
PROFILE_PIPELINE = "pipeline"
PROFILE_FULL = "full"
KNOWN_PROFILES: frozenset[str]

# Modèles
class DocumentMetricHook:    # frozen dataclass
class CorpusMetricAggregator:

# API
def validate_profile(profile)
def register_document_metric(*, name, attribute, profiles, ...) -> Callable
def register_corpus_aggregator(*, name, attribute, profiles) -> Callable
def select_document_hooks(profile) -> list[DocumentMetricHook]
def select_corpus_aggregators(profile) -> list[CorpusMetricAggregator]
def run_document_hooks(profile, *, ground_truth, hypothesis, image_path, corpus_lang, ocr_result) -> dict
def run_corpus_aggregators(profile, document_results) -> dict

picarones.evaluation.metrics.builtin_metrics

Métriques scalaires natives, enregistrées dans le registre typé :

def cer(reference, hypothesis) -> float
def wer(reference, hypothesis) -> float
def mer(reference, hypothesis) -> float
def wil(reference, hypothesis) -> float

# Stub démonstrateur
def text_preservation_after_reconstruction(reference_text, hypothesis_alto) -> float

picarones.evaluation.metrics.alto_metrics

Métriques (ALTO, ALTO) + helper :

def extract_text_from_alto(payload) -> str

def alto_text_cer(reference_alto, hypothesis_alto) -> float
def alto_text_wer(reference_alto, hypothesis_alto) -> float
def alto_text_mer(reference_alto, hypothesis_alto) -> float
def alto_text_wil(reference_alto, hypothesis_alto) -> float

picarones.interfaces.web.jobs

Persistance des jobs benchmark (utilisé par l'interface web) :

class JobStore:
def get_default_store() -> JobStore
def reset_default_store(...)

Politique de stabilité

Ce que nous garantissons

  • Existence : aucun nom listé ne disparaît entre 1.x.0 et 1.y.0 (pour y > x).
  • Signatures : aucun argument requis ajouté à une fonction publique. Les nouveaux arguments sont keyword avec valeur par défaut.
  • Types de retour : compatibles entre versions mineures (un dict peut gagner des clés mais pas en perdre).
  • Sémantique : un nom listé garde le même comportement fonctionnel. Les corrections de bug sont permises.

Ce que nous ne garantissons pas

  • Modules picarones.evaluation.metrics/ : peuvent évoluer librement. Quand ils changent, les shims rétrocompat dans picarones.domain/ reflètent ces changements.
  • Modules picarones.evaluation.metrics/ : statut variable selon le sous-package (academic / governance / historical / importers). Voir docs/explanation/architecture.md.
  • Comportement des renderers HTML : la structure des fichiers HTML peut évoluer entre versions mineures. Nous gardons les noms des vues principales.
  • Internes des modules canoniques : les noms commençant par _ ne font pas partie de l'API publique. Les tests Sprints historiques qui les importent (Sprint 13/42) sont préservés mais par effort, pas par contrat.

Bump majeur (2.0.0)

Un bump majeur sera nécessaire pour :

  • Supprimer un nom de cette liste.
  • Changer la signature d'une fonction publique de manière non rétrocompatible.
  • Casser le format de sérialisation du BenchmarkResult.to_json().
  • Renommer un module de l'arborescence canonique.

Chemins canoniques par couche

L'arborescence v2.0 expose des points d'entrée stables organisés par couche. Toutes les intégrations doivent passer par ces chemins — plus de path legacy disponible.

Couche 3 — picarones.evaluation

# Métriques (CER/WER + métriques avancées)
from picarones.evaluation.metrics.confusion import build_confusion_matrix
from picarones.evaluation.metrics.taxonomy import classify_errors
from picarones.evaluation.metrics.calibration import compute_calibration_metrics

# Moteur narratif (Cercle 7 → reports/, mais le contrat est en
# couche 3 pour rester accessible aux consommateurs externes)
from picarones.reports.narrative import build_synthesis
from picarones.domain.facts import Fact, FactType, FactImportance

# Modules philologiques (Sprints 55-60)
from picarones.evaluation.metrics.unicode_blocks import compute_unicode_block_accuracy
from picarones.evaluation.metrics.module_policy import ModuleManifest

Couche 5 — picarones.adapters

# OCR (factory canonique)
from picarones.adapters.ocr import ocr_adapter_from_name
from picarones.adapters.ocr import (
    TesseractAdapter, PeroOCRAdapter, KrakenAdapter, CalamariAdapter,
    MistralOCRAdapter, GoogleVisionAdapter, AzureDocIntelAdapter,
    PrecomputedTextAdapter,
)

# LLM
from picarones.adapters.llm.openai_adapter import OpenAIAdapter
from picarones.adapters.llm.anthropic_adapter import AnthropicAdapter
from picarones.adapters.llm.mistral_adapter import MistralAdapter
from picarones.adapters.llm.ollama_adapter import OllamaAdapter

# Importers de corpus distants
from picarones.adapters.corpus.iiif import IIIFImporter
from picarones.adapters.corpus.htr_united import HTRUnitedCatalogue
from picarones.adapters.corpus.huggingface import HuggingFaceImporter

Couche 6 — picarones.app.services

# Orchestration benchmark
from picarones.app.services.benchmark_runner import run_benchmark_via_service
from picarones.app.services.corpus_service import CorpusService
from picarones.app.services.path_security import (
    WorkspaceManager,
    validated_path,
    safe_report_name,
    validated_prompt_filename,
)
from picarones.app.services.partial_store import (
    compute_run_fingerprint,
    partial_path_for_engine,
)

Couche 7 — picarones.reports.html

from picarones.reports.html.generator import ReportGenerator

Couche 8 — picarones.interfaces

# CLI : exposée comme entry point ``picarones`` (cf. pyproject.toml).
# Pas d'API Python stable — l'invocation est ``picarones run/diagnose/…``.

# Web : FastAPI app (intégration via ASGI).
from picarones.interfaces.web.app import app
from picarones.interfaces.web.models import (
    PipelineConfig, PipelineMode,
    BenchmarkRequest, BenchmarkRunRequest,
    NormalizationProfileId, TesseractLang, ReportLang,
)

Voir aussi