bio-nexus-api / pathways.py
Samad14's picture
Add sequencing pipeline (FASTQ -> QC -> alignment -> variant calling -> report)
da793ed verified
Raw
History Blame Contribute Delete
3.28 kB
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)")
@router.post("/search")
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)}
@router.post("/detail")
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', '')}",
}