Spaces:
Sleeping
Sleeping
Jonas
Add initial implementation of ADE Explorer with requirements, plotting, and API client
dd19932
| import requests | |
| from cachetools import TTLCache, cached | |
| import time | |
| API_BASE_URL = "https://api.fda.gov/drug/event.json" | |
| # Cache with a TTL of 10 minutes (600 seconds) | |
| cache = TTLCache(maxsize=256, ttl=600) | |
| # 240 requests per minute per IP. A 0.25s delay is a simple way to stay under. | |
| REQUEST_DELAY_SECONDS = 0.25 | |
| def get_top_adverse_events(drug_name: str, limit: int = 10) -> dict: | |
| """ | |
| Query OpenFDA to get the top adverse events for a given drug. | |
| Args: | |
| drug_name (str): The name of the drug to search for (brand or generic). | |
| limit (int): The maximum number of adverse events to return. | |
| Returns: | |
| dict: The JSON response from the API, or an error dictionary. | |
| """ | |
| if not drug_name: | |
| return {"error": "Drug name cannot be empty."} | |
| drug_name_processed = drug_name.lower().strip() | |
| # Using a simple cache key | |
| cache_key = f"top_events_{drug_name_processed}_{limit}" | |
| if cache_key in cache: | |
| return cache[cache_key] | |
| query = ( | |
| f'search=patient.drug.medicinalproduct:"{drug_name_processed}"' | |
| f'&count=patient.reaction.reactionmeddrapt.exact&limit={limit}' | |
| ) | |
| try: | |
| # Respect rate limits | |
| time.sleep(REQUEST_DELAY_SECONDS) | |
| response = requests.get(f"{API_BASE_URL}?{query}") | |
| response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) | |
| data = response.json() | |
| cache[cache_key] = data | |
| return data | |
| except requests.exceptions.HTTPError as http_err: | |
| if response.status_code == 404: | |
| return {"error": f"No data found for drug: '{drug_name}'. It might be misspelled or not in the database."} | |
| return {"error": f"HTTP error occurred: {http_err}"} | |
| except requests.exceptions.RequestException as req_err: | |
| return {"error": f"A network request error occurred: {req_err}"} | |
| except Exception as e: | |
| return {"error": f"An unexpected error occurred: {e}"} | |
| def get_drug_event_pair_frequency(drug_name: str, event_name: str) -> dict: | |
| """ | |
| Query OpenFDA to get the total number of reports for a specific | |
| drug-adverse event pair. | |
| Args: | |
| drug_name (str): The name of the drug. | |
| event_name (str): The name of the adverse event. | |
| Returns: | |
| dict: The JSON response from the API, or an error dictionary. | |
| """ | |
| if not drug_name or not event_name: | |
| return {"error": "Drug name and event name cannot be empty."} | |
| drug_name_processed = drug_name.lower().strip() | |
| event_name_processed = event_name.lower().strip() | |
| cache_key = f"pair_freq_{drug_name_processed}_{event_name_processed}" | |
| if cache_key in cache: | |
| return cache[cache_key] | |
| query = ( | |
| f'search=patient.drug.medicinalproduct:"{drug_name_processed}"' | |
| f'+AND+patient.reaction.reactionmeddrapt:"{event_name_processed}"' | |
| ) | |
| try: | |
| time.sleep(REQUEST_DELAY_SECONDS) | |
| response = requests.get(f"{API_BASE_URL}?{query}") | |
| response.raise_for_status() | |
| data = response.json() | |
| cache[cache_key] = data | |
| return data | |
| except requests.exceptions.HTTPError as http_err: | |
| if response.status_code == 404: | |
| return {"error": f"No data found for drug '{drug_name}' and event '{event_name}'. They may be misspelled or not in the database."} | |
| return {"error": f"HTTP error occurred: {http_err}"} | |
| except requests.exceptions.RequestException as req_err: | |
| return {"error": f"A network request error occurred: {req_err}"} | |
| except Exception as e: | |
| return {"error": f"An unexpected error occurred: {e}"} | |