Source code for tooluniverse.euhealth.euhealth_tool
"""
EU Health Information Portal runtime utilities: topic search and deep dive.
Exports
-------
- TOPICS : Dict[str, dict]
Topic specs with seed terms and (optional) theme URI prefixes for filtering.
- euhealthinfo_search_* functions
One per topic; run keyword/embedding/hybrid search over the local "euhealth" collection
and return normalized dataset summaries (uuid/title/landing_page/license/keywords/themes/language/spatial/snippet).
- euhealthinfo_deepdive(uuids=None, topic=None, links_per=3, method="hybrid", limit=10, ...)
For explicit UUIDs or the top-N seeds from a topic, fetch landing pages and classify outgoing links:
direct_file | html_portal | login_or_error | error | unknown (with status/type when available).
Assumptions
-----------
- The "euhealth" collection exists locally as <user_cache_dir>/embeddings/euhealth.db and euhealth.faiss.
- Themes are compared case-insensitively (specs may use uppercase ontology prefixes; data is lowercased URIs).
Notes
-----
- De-duplicates results by dataset UUID when merging hits.
- Network access is required only for deep dive.
"""
from typing import Dict, Any, List, Optional
from tooluniverse.base_tool import BaseTool
from tooluniverse.tool_registry import register_tool
# Import the runtime surface (topic functions + deep dive).
from tooluniverse.euhealth import tools_runtime as rt
[docs]
@register_tool("EuHealthTopicSearchTool")
class EuHealthTopicSearchTool(BaseTool):
"""
Generic wrapper for all EU Health 'topic search' tools.
- 20 topic tools are defined in euhealth_tools.json.
- Each JSON entry sets fields.topic = the function name (e.g., "euhealthinfo_search_cancer").
- At runtime, this class dispatches the call to that function in tools_runtime.
Arguments supported:
- limit: int (default 25)
- country: Optional[str]
- language: Optional[str]
- term_override: Optional[str]
Returns:
List[Dict[str, Any]] shaped by _topic_search, including
{uuid, title, landing_page, license, keywords[], themes[], language[], spatial, snippet}.
"""
[docs]
def run(self, arguments: Dict[str, Any]) -> Any:
"""Dispatch to the configured topic function in tools_runtime.
Expects the tool config to include fields.topic with the function name.
Returns a shaped list of dataset summaries or an error dict.
"""
topic = (self.tool_config.get("fields") or {}).get("topic")
if not topic:
return {
"error": "EuHealthTopicSearchTool misconfigured: missing fields.topic in tool config"
}
fn = getattr(rt, topic, None)
if fn is None or not callable(fn):
return {"error": f"Topic function '{topic}' not found in tools_runtime"}
limit: int = int(arguments.get("limit", 25))
country: Optional[str] = arguments.get("country")
language: Optional[str] = arguments.get("language")
term_override: Optional[str] = arguments.get("term_override")
try:
return fn(
limit=limit,
country=country,
language=language,
term_override=term_override,
)
except Exception as e:
return {"error": f"euhealth topic search failed: {e}", "topic": topic}
[docs]
@register_tool("EuHealthDeepDiveTool")
class EuHealthDeepDiveTool(BaseTool):
"""
Adapter for the EU Health deep dive function.
Usage:
- Provide uuids=[...] to dive specific datasets.
- Or provide topic="euhealthinfo_search_cancer" to auto-select top-N datasets and dive them.
Arguments supported:
- uuids: Optional[List[str]]
- topic: Optional[str]
- limit: int (default 10, topic mode only)
- links_per: int (default 3)
- country: Optional[str] (topic mode only)
- language: Optional[str] (topic mode only)
- term_override: Optional[str] (topic mode only)
Returns:
List[Dict[str, Any]] with
{ uuid, title, landing_page,
candidates: [ {url, classification, http_status?, content_type?, notes?}, ... ]
}
"""
[docs]
def run(self, arguments: Dict[str, Any]) -> Any:
"""Run euhealth deep dive by explicit `uuids` or by a topic seed list.
Returns a list of {uuid, title, landing_page, candidates:[...]} or an error dict.
"""
uuids: Optional[List[str]] = arguments.get("uuids")
topic: Optional[str] = arguments.get("topic")
limit: int = int(arguments.get("limit", 10))
links_per: int = int(arguments.get("links_per", 3))
country: Optional[str] = arguments.get("country")
language: Optional[str] = arguments.get("language")
term_override: Optional[str] = arguments.get("term_override")
if not uuids and not topic:
return {
"error": "Provide either 'uuids' (preferred) or 'topic' to run deep dive"
}
try:
if uuids:
return rt.euhealthinfo_deepdive(
uuids=uuids,
limit=limit,
links_per=links_per,
country=country,
language=language,
term_override=term_override,
)
else:
if not hasattr(rt, topic):
return {"error": f"Unknown topic '{topic}' for deep dive"}
return rt.euhealthinfo_deepdive(
topic=topic,
limit=limit,
links_per=links_per,
country=country,
language=language,
term_override=term_override,
)
except Exception as e:
return {"error": f"euhealth deep dive failed: {e}"}