Spaces:
Sleeping
Sleeping
| import httpx | |
| from fastapi import APIRouter, HTTPException | |
| from pydantic import BaseModel, Field | |
| router = APIRouter() | |
| REACTOME_BASE = "https://reactome.org/ContentService" | |
| class PathwaySearchRequest(BaseModel): | |
| query: str = Field(..., min_length=2, description="Gene name or protein identifier") | |
| species: str = Field("Homo sapiens", description="Species name") | |
| class PathwayDetailRequest(BaseModel): | |
| pathway_id: str = Field(..., min_length=1, description="Reactome pathway ID (e.g. R-HSA-1640170)") | |
| async def search_pathways(req: PathwaySearchRequest): | |
| # Try Reactome text search first (handles gene names, proteins, pathways) | |
| async with httpx.AsyncClient(timeout=15) as client: | |
| resp = await client.get( | |
| f"{REACTOME_BASE}/search/query", | |
| params={"query": req.query, "species": req.species, "types": "Pathway"}, | |
| ) | |
| if resp.status_code != 200: | |
| raise HTTPException(status_code=502, detail="Reactome search failed") | |
| data = resp.json() | |
| results = [] | |
| seen = set() | |
| for item in data if isinstance(data, list) else []: | |
| st_id = item.get("stId", "") | |
| if not st_id or st_id in seen: | |
| continue | |
| seen.add(st_id) | |
| results.append({ | |
| "pathway_id": st_id, | |
| "name": item.get("displayName", ""), | |
| "species": (item.get("species", {}) or {}).get("name", ""), | |
| "url": f"https://reactome.org/content/detail/{st_id}", | |
| }) | |
| # If text search gave nothing, try fireworks search (pathway hierarchy) | |
| if not results: | |
| async with httpx.AsyncClient(timeout=15) as client: | |
| resp = await client.get( | |
| f"{REACTOME_BASE}/search/fireworks", | |
| params={"query": req.query, "species": req.species}, | |
| ) | |
| if resp.status_code == 200: | |
| data = resp.json() | |
| for item in data if isinstance(data, list) else []: | |
| st_id = item.get("stId", "") | |
| if not st_id or st_id in seen: | |
| continue | |
| seen.add(st_id) | |
| results.append({ | |
| "pathway_id": st_id, | |
| "name": item.get("name", ""), | |
| "species": (item.get("species", {}) or {}).get("name", ""), | |
| "url": f"https://reactome.org/content/detail/{st_id}", | |
| }) | |
| return {"results": results, "count": len(results)} | |
| async def pathway_detail(req: PathwayDetailRequest): | |
| async with httpx.AsyncClient(timeout=15) as client: | |
| resp = await client.get(f"{REACTOME_BASE}/data/fireworks/{req.pathway_id}") | |
| if resp.status_code != 200: | |
| raise HTTPException(status_code=404, detail="Pathway not found") | |
| data = resp.json() | |
| return { | |
| "pathway_id": data.get("stId", ""), | |
| "name": data.get("name", ""), | |
| "species": (data.get("species", {}) or {}).get("name", ""), | |
| "description": data.get("definition", ""), | |
| "url": f"https://reactome.org/content/detail/{data.get('stId', '')}", | |
| } | |