| | |
| |
|
| | |
| | """MedGenesis – **openFDA** drug‑event wrapper (async, cached). |
| | |
| | Enhancements over the legacy helper |
| | ----------------------------------- |
| | * Back‑off retry (2×, 4×, 8×) for intermittent 503s. |
| | * `@lru_cache` (12 h, 512 keys) to spare quota. |
| | * Returns empty list instead of raising on any service hiccup. |
| | * Accepts optional `limit` kwarg (capped at 20). |
| | * Normalises API response to `schemas.DrugSafety`‑compatible dicts. |
| | |
| | API docs: https://open.fda.gov/apis/drug/event/ |
| | """ |
| | from __future__ import annotations |
| |
|
| | import asyncio, httpx |
| | from functools import lru_cache |
| | from typing import List, Dict |
| |
|
| | _URL = "https://api.fda.gov/drug/event.json" |
| | _TIMEOUT = 15 |
| | _MAX_LIMIT = 20 |
| |
|
| | |
| | |
| | |
| | async def _get(params: Dict, *, retries: int = 3) -> Dict: |
| | delay = 2 |
| | last = None |
| | for _ in range(retries): |
| | async with httpx.AsyncClient(timeout=_TIMEOUT) as cli: |
| | last = await cli.get(_URL, params=params) |
| | if last.status_code == 200: |
| | return last.json() |
| | await asyncio.sleep(delay) |
| | delay *= 2 |
| | return last.json() if last else {} |
| |
|
| |
|
| | |
| | |
| | |
| | @lru_cache(maxsize=512) |
| | async def fetch_drug_safety(drug: str, *, limit: int = 3) -> List[Dict]: |
| | """Return recent adverse‑event reports for *drug* (empty list on failure).""" |
| | limit = max(1, min(limit, _MAX_LIMIT)) |
| | params = { |
| | "search": f'patient.drug.medicinalproduct:"{drug}"', |
| | "limit" : limit, |
| | } |
| |
|
| | try: |
| | data = await _get(params) |
| | rows = data.get("results", []) |
| | out: List[Dict] = [] |
| | for ev in rows: |
| | out.append({ |
| | "safety_report_id": ev.get("safetyreportid"), |
| | "serious" : ev.get("serious"), |
| | "reactions" : [r.get("reactionmeddrapt") for r in ev.get("patient", {}).get("reaction", [])], |
| | "receivedate" : ev.get("receivedate"), |
| | }) |
| | return out |
| | except Exception: |
| | return [] |
| |
|
| |
|
| | |
| | if __name__ == "__main__": |
| | import asyncio, json |
| | async def _demo(): |
| | res = await fetch_drug_safety("temozolomide", limit=2) |
| | print(json.dumps(res, indent=2)) |
| | asyncio.run(_demo()) |
| |
|