Update mcp/mygene.py
Browse files- mcp/mygene.py +10 -57
mcp/mygene.py
CHANGED
@@ -1,58 +1,11 @@
|
|
1 |
-
|
2 |
-
"""MedGenesis – MyGene.info async helper (timeout‑safe).
|
3 |
-
|
4 |
-
Provides `fetch_gene_info(query)` → first hit dict or `{}`.
|
5 |
-
Adds:
|
6 |
-
* 3‑step back‑off retry (2 s → 4 s → 8 s) on time‑outs/429/5xx.
|
7 |
-
* 10 s client timeout.
|
8 |
-
* 24 h LRU cache (128 queries).
|
9 |
-
* Returns empty dict on any failure so orchestrator can’t crash.
|
10 |
-
"""
|
11 |
-
from __future__ import annotations
|
12 |
-
|
13 |
-
import asyncio, httpx
|
14 |
from functools import lru_cache
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
try:
|
25 |
-
async with httpx.AsyncClient(timeout=_TIMEOUT) as client:
|
26 |
-
resp = await client.get(f"{_BASE}/query", params=params)
|
27 |
-
if resp.status_code == 200:
|
28 |
-
hits = resp.json().get("hits", [])
|
29 |
-
return hits[0] if hits else {}
|
30 |
-
if resp.status_code in {429, 500, 502, 503, 504}:
|
31 |
-
raise httpx.HTTPStatusError("retry", request=resp.request, response=resp)
|
32 |
-
except (httpx.HTTPStatusError, httpx.ReadTimeout):
|
33 |
-
if attempt == _MAX_RETRIES - 1:
|
34 |
-
return {}
|
35 |
-
await asyncio.sleep(delay)
|
36 |
-
delay *= 2
|
37 |
-
except Exception:
|
38 |
-
return {}
|
39 |
-
return {}
|
40 |
-
|
41 |
-
@lru_cache(maxsize=128)
|
42 |
-
async def fetch_gene_info(query: str) -> Dict: # noqa: D401
|
43 |
-
"""Return MyGene.info top hit or empty dict (never raises)."""
|
44 |
-
params = {
|
45 |
-
"q": query,
|
46 |
-
"fields": "symbol,name,summary,alias,entrezgene,clinvar,location,go",
|
47 |
-
"size": 1,
|
48 |
-
}
|
49 |
-
return await _query_mygene(params)
|
50 |
-
|
51 |
-
# ------------------------------------------------------------------
|
52 |
-
# CLI demo
|
53 |
-
# ------------------------------------------------------------------
|
54 |
-
if __name__ == "__main__":
|
55 |
-
import json, asyncio
|
56 |
-
async def _demo():
|
57 |
-
print(json.dumps(await fetch_gene_info("TP53"), indent=2))
|
58 |
-
asyncio.run(_demo())
|
|
|
1 |
+
import os, httpx, asyncio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
from functools import lru_cache
|
3 |
+
_KEY = os.getenv("MYGENE_KEY"); _URL="https://mygene.info/v3/query"
|
4 |
+
@lru_cache(maxsize=512)
|
5 |
+
async def fetch_gene_info(sym: str):
|
6 |
+
p={"q":sym,"fields":"symbol,name,summary,alias,entrezgene,location","size":1}
|
7 |
+
if _KEY: p["api_key"]=_KEY
|
8 |
+
async with httpx.AsyncClient(timeout=8) as c:
|
9 |
+
r=await c.get(_URL,params=p); r.raise_for_status()
|
10 |
+
return r.json().get("hits",[{}])[0]
|
11 |
+
``` :contentReference[oaicite:7]{index=7}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|