Spaces:
Sleeping
Sleeping
| """Client API AGRIBALYSE - Données environnementales alimentaires.""" | |
| import httpx | |
| from typing import Any | |
| BASE_URL = "https://data.ademe.fr/data-fair/api/v1/datasets/agribalyse-31-synthese" | |
| class AgribalyseClient: | |
| """Client async pour l'API AGRIBALYSE.""" | |
| def __init__(self, timeout: float = 30.0): | |
| self.timeout = timeout | |
| self._client: httpx.AsyncClient | None = None | |
| async def _get_client(self) -> httpx.AsyncClient: | |
| if self._client is None: | |
| self._client = httpx.AsyncClient(timeout=self.timeout) | |
| return self._client | |
| async def close(self): | |
| if self._client: | |
| await self._client.aclose() | |
| self._client = None | |
| async def search( | |
| self, | |
| query: str, | |
| size: int = 10, | |
| select: list[str] | None = None | |
| ) -> dict[str, Any]: | |
| """Recherche d'aliments dans AGRIBALYSE. | |
| Args: | |
| query: Terme de recherche (ex: "boeuf", "pomme") | |
| size: Nombre de résultats (max 100) | |
| select: Champs à retourner (None = tous) | |
| Returns: | |
| Dict avec total et results | |
| """ | |
| client = await self._get_client() | |
| params = { | |
| "q": query, | |
| "size": min(size, 100) | |
| } | |
| if select: | |
| params["select"] = ",".join(select) | |
| response = await client.get(f"{BASE_URL}/lines", params=params) | |
| response.raise_for_status() | |
| return response.json() | |
| async def get_by_code(self, code_ciqual: int) -> dict[str, Any] | None: | |
| """Récupère un aliment par son code CIQUAL. | |
| Args: | |
| code_ciqual: Code CIQUAL de l'aliment | |
| Returns: | |
| Données de l'aliment ou None | |
| """ | |
| client = await self._get_client() | |
| params = { | |
| "qs": f"Code_CIQUAL:{code_ciqual}", | |
| "size": 1 | |
| } | |
| response = await client.get(f"{BASE_URL}/lines", params=params) | |
| response.raise_for_status() | |
| data = response.json() | |
| if data.get("results"): | |
| return data["results"][0] | |
| return None | |
| async def get_categories(self) -> list[str]: | |
| """Liste les groupes d'aliments disponibles. | |
| Returns: | |
| Liste des groupes d'aliments uniques | |
| """ | |
| client = await self._get_client() | |
| response = await client.get( | |
| f"{BASE_URL}/values_agg", | |
| params={"field": "Groupe_d'aliment", "size": 100} | |
| ) | |
| response.raise_for_status() | |
| data = response.json() | |
| return [item["value"] for item in data.get("aggs", [])] | |
| async def get_subcategories(self, group: str) -> list[str]: | |
| """Liste les sous-groupes d'un groupe d'aliments. | |
| Args: | |
| group: Nom du groupe d'aliments | |
| Returns: | |
| Liste des sous-groupes | |
| """ | |
| client = await self._get_client() | |
| response = await client.get( | |
| f"{BASE_URL}/values_agg", | |
| params={ | |
| "field": "Sous-groupe_d'aliment", | |
| "size": 100, | |
| "qs": f"Groupe_d'aliment:\"{group}\"" | |
| } | |
| ) | |
| response.raise_for_status() | |
| data = response.json() | |
| return [item["value"] for item in data.get("aggs", [])] | |
| # Champs principaux AGRIBALYSE pour référence | |
| AGRIBALYSE_FIELDS = { | |
| "identite": [ | |
| "Code_CIQUAL", | |
| "Code_AGB", | |
| "Nom_du_Produit_en_Français", | |
| "LCI_Name", | |
| "Groupe_d'aliment", | |
| "Sous-groupe_d'aliment", | |
| ], | |
| "impact_climatique": [ | |
| "Changement_climatique", | |
| "Changement_climatique_-_émissions_fossiles", | |
| "Changement_climatique_-_émissions_biogéniques", | |
| "Changement_climatique_-_émissions_liées_au_changement_d'affectation_des_sols", | |
| ], | |
| "autres_impacts": [ | |
| "Score_unique_EF", | |
| "Acidification_terrestre_et_eaux_douces", | |
| "Eutrophisation_marine", | |
| "Eutrophisation_eaux_douces", | |
| "Eutrophisation_terrestre", | |
| "Utilisation_du_sol", | |
| "Épuisement_des_ressources_eau", | |
| "Épuisement_des_ressources_énergétiques", | |
| "Épuisement_des_ressources_minéraux", | |
| "Particules_fines", | |
| "Formation_photochimique_d'ozone", | |
| "Appauvrissement_de_la_couche_d'ozone", | |
| "Rayonnements_ionisants", | |
| "Écotoxicité_pour_écosystèmes_aquatiques_d'eau_douce", | |
| "Effets_toxicologiques_sur_la_santé_humaine___substances_cancérogènes", | |
| "Effets_toxicologiques_sur_la_santé_humaine___substances_non-cancérogènes", | |
| ], | |
| "qualite": [ | |
| "DQR", | |
| ], | |
| "contexte": [ | |
| "Livraison", | |
| "Préparation", | |
| "Approche_emballage_", | |
| "code_avion", | |
| "code_saison", | |
| ], | |
| } | |