tooluniverse.cancervar_tool 源代码
"""
CancerVar Tool
CancerVar implements the AMP/ASCO/CAP 2017 guidelines for clinical interpretation of
somatic variants in cancer. Given a genomic variant (chromosome, position, ref, alt),
it returns a tier classification (Tier I–IV) together with all AMP/ASCO/CAP Biomarker
Prioritization (CBP) criteria scores and an oncogenicity index (OPAI).
Tiers:
Tier I – Variants of Strong Clinical Significance
Tier II – Variants of Potential Clinical Significance
Tier III – Variants of Unknown Clinical Significance
Tier IV – Benign or Likely Benign Variants
API: http://cancervar.wglab.org/api_new.php
No authentication required.
"""
import requests
from typing import Dict, Any
from .base_tool import BaseTool
from .tool_registry import register_tool
from .intervar_tool import InterVarTool
CANCERVAR_BASE_URL = "http://cancervar.wglab.org/api_new.php"
# AMP/ASCO/CAP CBP criteria descriptions
CBP_DESCRIPTIONS = {
"CBP_1": "FDA-approved or well-established therapeutic association (same cancer type)",
"CBP_2": "FDA-approved or well-established therapeutic association (different cancer type)",
"CBP_3": "Evidence from well-powered studies with consensus (investigational biomarker)",
"CBP_4": "Evidence from multiple small studies (investigational biomarker, same cancer type)",
"CBP_5": "Preclinical studies only",
"CBP_6": "No evidence for oncogenic function",
"CBP_7": "Listed in cancer mutation hotspot databases",
"CBP_8": "Observed in functional domain with established cancer mechanism",
"CBP_9": "Population allele frequency (0=common, 1=rare, 2=absent/very rare)",
"CBP_10": "Predicted damaging by computational tools",
"CBP_11": "Listed as somatic mutation in cancer databases (COSMIC, cBioPortal)",
"CBP_12": "Literature-reported as somatic mutation in cancer",
}
TIER_DESCRIPTIONS = {
"Tier_I_strong": "Tier I – Variants of Strong Clinical Significance (FDA-approved or well-established)",
"Tier_II_potential": "Tier II – Variants of Potential Clinical Significance (investigational/preclinical evidence)",
"Tier_III_unknown": "Tier III – Variants of Unknown Clinical Significance",
"Tier_IV_benign": "Tier IV – Benign or Likely Benign Variants",
}
[文档]
@register_tool("CancerVarTool")
class CancerVarTool(BaseTool):
"""
CancerVar: AMP/ASCO/CAP 2017 somatic variant interpretation tool.
Classifies somatic cancer variants into four tiers per the AMP/ASCO/CAP 2017
guidelines: Tier I (strong clinical significance), Tier II (potential clinical
significance), Tier III (unknown significance), Tier IV (benign/likely benign).
Returns all 12 CBP criteria scores, the tier assignment, and the Oncogenicity
Pathogenicity Index (OPAI, 0–1).
Input: genomic coordinates (chr, pos, ref, alt) in hg19 or hg38.
No authentication required.
"""
[文档]
def __init__(self, tool_config: Dict[str, Any]):
super().__init__(tool_config)
self.timeout = tool_config.get("timeout", 30)
self.operation = tool_config.get("fields", {}).get("operation", "classify")
[文档]
def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
op = self.operation
if op == "classify":
return self._classify_variant(arguments)
return {"status": "error", "error": f"Unknown operation: {op}"}
[文档]
def _classify_variant(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
params, err = InterVarTool._parse_variant_args(arguments)
if err:
return err
try:
resp = requests.get(CANCERVAR_BASE_URL, params=params, timeout=self.timeout)
resp.raise_for_status()
raw = resp.json()
except requests.exceptions.Timeout:
return {
"status": "error",
"error": f"CancerVar API timeout after {self.timeout}s",
}
except requests.exceptions.RequestException as e:
return {"status": "error", "error": f"CancerVar API request failed: {e}"}
except Exception as e:
return {"status": "error", "error": f"Failed to parse response: {e}"}
if not isinstance(raw, dict) or "Cancervar" not in raw:
return {
"status": "error",
"error": "Unexpected response format from CancerVar API",
"raw": raw,
}
cancervar_str = raw["Cancervar"]
tier_label = cancervar_str
tier_score = None
if "#" in cancervar_str:
parts = cancervar_str.split("#", 1)
try:
tier_score = int(parts[0])
except ValueError:
pass
tier_label = parts[1] if len(parts) > 1 else cancervar_str
tier_description = TIER_DESCRIPTIONS.get(tier_label, tier_label)
cbp_criteria = {
k: {"value": raw.get(k), "description": CBP_DESCRIPTIONS.get(k, k)}
for k in CBP_DESCRIPTIONS
if k in raw
}
opai = raw.get("OPAI")
return {
"status": "success",
"data": {
"tier": tier_label,
"tier_score": tier_score,
"tier_description": tier_description,
"opai": opai,
"variant": {
"chromosome": raw.get("Chromosome"),
"position": raw.get("Position"),
"ref_allele": raw.get("Ref_allele"),
"alt_allele": raw.get("Alt_allele"),
"gene": raw.get("Gene"),
"build": raw.get("Build"),
},
"cbp_criteria": cbp_criteria,
},
"metadata": {
"source": "CancerVar (cancervar.wglab.org)",
"guideline": "AMP/ASCO/CAP 2017 Standards and Guidelines",
"tier_categories": list(TIER_DESCRIPTIONS.values()),
"opai_range": "0.0–1.0 (higher = more likely oncogenic/pathogenic)",
},
}