"""Modèles Pydantic pour le MCP Server ADEME.""" from pydantic import BaseModel, Field from typing import Any class EmissionFactor(BaseModel): """Facteur d'émission unifié (AGRIBALYSE ou Base Carbone).""" source: str = Field(description="Source: 'agribalyse' ou 'base_carbone'") id: str = Field(description="Identifiant unique") name: str = Field(description="Nom en français") value: float = Field(description="Valeur du FE en kgCO2e") unit: str = Field(description="Unité (kgCO2e/kg, kgCO2e/km, etc.)") category: str = Field(description="Catégorie") # Qualité uncertainty: float | None = Field(default=None, description="Incertitude en %") dqr: float | None = Field(default=None, description="Data Quality Rating (1-5)") # Métadonnées methodology_source: str | None = Field(default=None, description="Source méthodologique") validity_period: str | None = Field(default=None, description="Période de validité") status: str | None = Field(default=None, description="Statut (Valide, Archivé)") class FoodItem(BaseModel): """Aliment AGRIBALYSE avec impacts environnementaux.""" code_ciqual: int = Field(description="Code CIQUAL") code_agb: str = Field(description="Code AGRIBALYSE") name_fr: str = Field(description="Nom en français") name_en: str | None = Field(default=None, description="Nom en anglais") group: str = Field(description="Groupe d'aliment") subgroup: str = Field(description="Sous-groupe d'aliment") # Impact climatique climate_change: float = Field(description="Impact changement climatique (kgCO2e/kg)") climate_change_fossil: float | None = Field(default=None, description="Émissions fossiles") climate_change_biogenic: float | None = Field(default=None, description="Émissions biogéniques") climate_change_land_use: float | None = Field(default=None, description="Changement d'affectation des sols") # Score global ef_score: float | None = Field(default=None, description="Score unique EF") dqr: float | None = Field(default=None, description="Data Quality Rating") # Contexte delivery: str | None = Field(default=None, description="Mode de livraison") preparation: str | None = Field(default=None, description="Mode de préparation") packaging: str | None = Field(default=None, description="Type d'emballage") by_plane: bool = Field(default=False, description="Transport par avion") class TransportFactor(BaseModel): """Facteur d'émission transport.""" id: str vehicle_type: str = Field(description="Type de véhicule") fuel_type: str | None = Field(default=None, description="Type de carburant") attribute: str | None = Field(default=None, description="Attribut (tonnage, etc.)") value: float = Field(description="Valeur en kgCO2e") unit: str = Field(description="Unité (kgCO2e/km, kgCO2e/t.km, etc.)") uncertainty: float | None = Field(default=None, description="Incertitude %") source: str | None = Field(default=None, description="Source") status: str | None = Field(default=None, description="Statut") class EnergyFactor(BaseModel): """Facteur d'émission énergie.""" id: str energy_type: str = Field(description="Type d'énergie") specification: str | None = Field(default=None, description="Spécification") value: float = Field(description="Valeur en kgCO2e") unit: str = Field(description="Unité (kgCO2e/kWh, kgCO2e/kg, etc.)") # Décomposition par gaz co2_fossil: float | None = Field(default=None, description="CO2 fossile") co2_biogenic: float | None = Field(default=None, description="CO2 biogénique") ch4: float | None = Field(default=None, description="Méthane") n2o: float | None = Field(default=None, description="Protoxyde d'azote") uncertainty: float | None = Field(default=None, description="Incertitude %") source: str | None = Field(default=None, description="Source") class WasteFactor(BaseModel): """Facteur d'émission déchets.""" id: str waste_type: str = Field(description="Type de déchet") treatment: str = Field(description="Traitement (compost, incinération, etc.)") value: float = Field(description="Valeur en kgCO2e/tonne") unit: str = Field(default="kgCO2e/tonne", description="Unité") # Décomposition par gaz co2_fossil: float | None = None co2_biogenic: float | None = None ch4: float | None = None n2o: float | None = None uncertainty: float | None = None source: str | None = None class ComparisonResult(BaseModel): """Résultat de comparaison entre 2 facteurs d'émission.""" factor1: EmissionFactor factor2: EmissionFactor absolute_difference: float = Field(description="Différence absolue (FE2 - FE1)") relative_difference: float = Field(description="Différence relative en %") # Analyse lower_bound_diff: float | None = Field( default=None, description="Différence min compte tenu des incertitudes" ) upper_bound_diff: float | None = Field( default=None, description="Différence max compte tenu des incertitudes" ) recommendation: str | None = Field( default=None, description="Recommandation d'usage" ) class SearchResult(BaseModel): """Résultat de recherche unifiée.""" total: int = Field(description="Nombre total de résultats") results: list[EmissionFactor] = Field(description="Facteurs d'émission trouvés") sources: dict[str, int] = Field( description="Nombre de résultats par source" )