tooluniverse.mutalyzer_tool 源代码

"""
Mutalyzer API tool for ToolUniverse.

Mutalyzer is a suite of programs for HGVS variant nomenclature checking,
normalization, and coordinate conversion. It validates variant descriptions
against reference sequences and provides protein-level predictions.

API: https://mutalyzer.nl/api
No authentication required.
"""

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

MUTALYZER_BASE = "https://mutalyzer.nl/api"


[文档] @register_tool("MutalyzerTool") class MutalyzerTool(BaseTool): """ Tool for HGVS variant nomenclature validation and normalization using the Mutalyzer API. Supports: normalize (validate + predict protein), back_translate (protein to DNA variants), description_to_model (parse HGVS to structured model). No authentication required. """
[文档] def __init__(self, tool_config: Dict[str, Any]): super().__init__(tool_config) self.timeout = tool_config.get("timeout", 30) self.endpoint_type = tool_config.get("fields", {}).get( "endpoint_type", "normalize" )
[文档] def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Execute the Mutalyzer API call.""" try: return self._query(arguments) except requests.exceptions.Timeout: return { "status": "error", "error": f"Mutalyzer API request timed out after {self.timeout}s", } except requests.exceptions.ConnectionError: return { "status": "error", "error": "Failed to connect to Mutalyzer API. Check network connectivity.", } except Exception as e: return { "status": "error", "error": f"Unexpected error querying Mutalyzer: {str(e)}", }
[文档] def _query(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Route to the appropriate Mutalyzer endpoint.""" if self.endpoint_type == "normalize": return self._normalize(arguments) elif self.endpoint_type == "back_translate": return self._back_translate(arguments) elif self.endpoint_type == "description_to_model": return self._description_to_model(arguments) return { "status": "error", "error": f"Unknown endpoint type: {self.endpoint_type}", }
[文档] def _normalize(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Validate and normalize an HGVS variant description.""" variant = arguments.get("variant", "") if not variant: return {"status": "error", "error": "variant parameter is required"} url = f"{MUTALYZER_BASE}/normalize/{variant}" resp = requests.get(url, timeout=self.timeout) resp.raise_for_status() data = resp.json() result = { "input_description": data.get("input_description"), "corrected_description": data.get("corrected_description"), "normalized_description": data.get("normalized_description"), "gene_id": data.get("gene_id"), } # Extract protein prediction if available protein = data.get("protein") if protein: result["protein"] = { "description": protein.get("description"), "reference_sequence": protein.get("reference"), "predicted_sequence": protein.get("predicted"), } # Extract RNA description if available rna = data.get("rna") if rna: result["rna_description"] = rna.get("description") # Extract errors and infos custom = data.get("custom", {}) errors = custom.get("errors", []) if isinstance(custom, dict) else [] if errors: result["errors"] = [ {"code": e.get("code"), "details": e.get("details")} for e in errors ] infos = data.get("infos", []) if infos: result["infos"] = infos return { "status": "success", "data": result, "metadata": { "source": "Mutalyzer", "api_version": "3", "query_variant": variant, }, }
[文档] def _back_translate(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Convert a protein variant description to possible DNA-level variants.""" variant = arguments.get("variant", "") if not variant: return {"status": "error", "error": "variant parameter is required"} url = f"{MUTALYZER_BASE}/back_translate/{variant}" resp = requests.get(url, timeout=self.timeout) resp.raise_for_status() data = resp.json() # API returns a list of possible DNA-level descriptions descriptions = data if isinstance(data, list) else [data] return { "status": "success", "data": { "input_protein_variant": variant, "dna_descriptions": descriptions, "count": len(descriptions), }, "metadata": { "source": "Mutalyzer", "api_version": "3", "query_variant": variant, }, }
[文档] def _description_to_model(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Parse an HGVS description into a structured model.""" variant = arguments.get("variant", "") if not variant: return {"status": "error", "error": "variant parameter is required"} url = f"{MUTALYZER_BASE}/description_to_model/{variant}" resp = requests.get(url, timeout=self.timeout) resp.raise_for_status() data = resp.json() return { "status": "success", "data": { "input_description": variant, "model": data, }, "metadata": { "source": "Mutalyzer", "api_version": "3", "query_variant": variant, }, }