Source code for tooluniverse.foodb_tool

"""
FooDB tool for ToolUniverse — food chemical-constituent database.

FooDB is the largest database of food constituents/chemicals (the molecules that
make up food, including phytochemicals and metabolites), complementary to nutrient
databases like USDA FoodData Central. This tool retrieves a food compound by its
FooDB id (FDB...), returning structure, properties, food-occurrence description, and
cross-references (HMDB, KEGG, PubChem, ChEBI) for ID bridging in food/metabolomics work.

API: https://foodb.ca/compounds/{FDB_id}.json  (public, no authentication, JSON)
Note: FooDB has no working name-search API; look up by FDB compound id.
"""

from typing import Any, Dict

import requests

from .base_tool import BaseTool
from .tool_registry import register_tool

FOODB_BASE = "https://foodb.ca/compounds"


[docs] @register_tool("FooDBCompoundTool") class FooDBCompoundTool(BaseTool): """Get a FooDB food-constituent compound by its FooDB id (FDB...)."""
[docs] def __init__(self, tool_config: Dict[str, Any]): super().__init__(tool_config) self.timeout = tool_config.get("fields", {}).get("timeout", 30)
[docs] def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]: fdb_id = (arguments.get("fdb_id") or "").strip().upper() if not fdb_id: return { "status": "error", "error": "'fdb_id' is required (a FooDB compound id, e.g. 'FDB000004')", } try: resp = requests.get( f"{FOODB_BASE}/{fdb_id}.json", headers={"Accept": "application/json"}, timeout=self.timeout, ) if resp.status_code == 404: return { "status": "success", "data": {}, "metadata": { "query_fdb_id": fdb_id, "note": f"No FooDB compound '{fdb_id}'.", }, } resp.raise_for_status() c = resp.json() except requests.exceptions.Timeout: return { "status": "error", "error": f"FooDB request timed out after {self.timeout}s", } except requests.exceptions.RequestException as e: return {"status": "error", "error": f"FooDB request failed: {e}"} except ValueError: return {"status": "error", "error": "FooDB returned a non-JSON response"} if not isinstance(c, dict) or not c.get("public_id"): return { "status": "success", "data": {}, "metadata": {"query_fdb_id": fdb_id}, } return { "status": "success", "data": { "fdb_id": c.get("public_id"), "name": c.get("name"), "description": c.get("description"), "cas_number": c.get("cas_number"), "formula": c.get("moldb_formula"), "smiles": c.get("moldb_smiles"), "inchi": c.get("moldb_inchi"), "inchikey": c.get("moldb_inchikey"), "logp": c.get("moldb_logp") or c.get("moldb_alogps_logp"), "solubility": c.get("moldb_alogps_solubility") or c.get("experimental_solubility"), "annotation_quality": c.get("annotation_quality"), "cross_references": { "hmdb_id": c.get("hmdb_id"), "kegg_compound_id": c.get("kegg_compound_id"), "pubchem_compound_id": c.get("pubchem_compound_id"), "chebi_id": c.get("chebi_id"), }, }, "metadata": {"query_fdb_id": fdb_id, "source": "FooDB"}, }