Source code for tooluniverse.civic_tool

"""
CIViC (Clinical Interpretation of Variants in Cancer) API tool for ToolUniverse.

CIViC is a community knowledgebase for expert-curated interpretations of variants
in cancer. It provides clinical evidence levels and interpretations.

API Documentation: https://civicdb.org/api
GraphQL Endpoint: https://civicdb.org/api/graphql
"""

import requests
from typing import Dict, Any, Optional
from .base_tool import BaseTool
from .tool_registry import register_tool

# Base URL for CIViC
CIVIC_BASE_URL = "https://civicdb.org/api"
CIVIC_GRAPHQL_URL = f"{CIVIC_BASE_URL}/graphql"


[docs] @register_tool("CIViCTool") class CIViCTool(BaseTool): """ Tool for querying CIViC (Clinical Interpretation of Variants in Cancer). CIViC provides: - Expert-curated cancer variant interpretations - Clinical evidence levels - Drug-variant associations - Disease-variant associations Uses GraphQL API. No authentication required. Free for academic/research use. """
[docs] def __init__(self, tool_config: Dict[str, Any]): super().__init__(tool_config) fields = tool_config.get("fields", {}) self.query_template: str = fields.get("query", "") self.operation_name: Optional[str] = fields.get("operation_name") self.timeout: int = tool_config.get("timeout", 30)
[docs] def _build_graphql_query(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Build GraphQL query from template and arguments.""" query = self.query_template # GraphQL queries use variables, not string replacement # Extract variable names from query (e.g., $limit, $gene_id) import re var_matches = re.findall(r"\$(\w+)", query) # Map arguments to GraphQL variables # GraphQL variable names match argument names in our config variables = {} for var_name in var_matches: # Check if argument exists (variable name matches argument name) if var_name in arguments: variables[var_name] = arguments[var_name] payload = {"query": query} if self.operation_name: payload["operationName"] = self.operation_name if variables: payload["variables"] = variables return payload
[docs] def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Execute the CIViC GraphQL API call.""" try: # Build GraphQL query payload = self._build_graphql_query(arguments) # Make GraphQL request response = requests.post( CIVIC_GRAPHQL_URL, json=payload, timeout=self.timeout, headers={ "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "ToolUniverse/CIViC", }, ) response.raise_for_status() data = response.json() # Check for GraphQL errors if "errors" in data: return { "error": "GraphQL query errors", "errors": data["errors"], "query": arguments, } return { "data": data.get("data", {}), "metadata": { "source": "CIViC (Clinical Interpretation of Variants in Cancer)", "format": "GraphQL", "endpoint": CIVIC_GRAPHQL_URL, }, } except requests.RequestException as e: return {"error": f"CIViC API request failed: {str(e)}", "query": arguments} except ValueError as e: return {"error": str(e), "query": arguments} except Exception as e: return {"error": f"Unexpected error: {str(e)}", "query": arguments}