Jonas commited on
Commit
fcabd7a
·
1 Parent(s): 3455d98

Update app.py to clarify drug name input as generic and enhance openfda_client.py with new outcome and qualification mappings for better data representation.

Browse files
Files changed (2) hide show
  1. app.py +5 -5
  2. openfda_client.py +25 -19
app.py CHANGED
@@ -39,7 +39,7 @@ def top_adverse_events_tool(drug_name: str, patient_sex: str = "all", min_age: i
39
  MCP Tool: Finds the top reported adverse events for a given drug.
40
 
41
  Args:
42
- drug_name (str): The name of the drug to search for.
43
  patient_sex (str): The patient's sex to filter by.
44
  min_age (int): The minimum age for the filter.
45
  max_age (int): The maximum age for the filter.
@@ -91,7 +91,7 @@ def serious_outcomes_tool(drug_name: str):
91
  MCP Tool: Finds the top reported serious outcomes for a given drug.
92
 
93
  Args:
94
- drug_name (str): The name of the drug to search for.
95
 
96
  Returns:
97
  tuple: A Plotly figure, a Pandas DataFrame, and a summary string.
@@ -123,7 +123,7 @@ def drug_event_stats_tool(drug_name: str, event_name: str):
123
  MCP Tool: Gets the total number of reports for a specific drug and adverse event pair.
124
 
125
  Args:
126
- drug_name (str): The name of the drug to search for.
127
  event_name (str): The name of the adverse event to search for.
128
 
129
  Returns:
@@ -137,7 +137,7 @@ def time_series_tool(drug_name: str, event_name: str, aggregation: str):
137
  MCP Tool: Creates a time-series plot for a drug-event pair.
138
 
139
  Args:
140
- drug_name (str): The name of the drug.
141
  event_name (str): The name of the adverse event.
142
  aggregation (str): Time aggregation ('Yearly' or 'Quarterly').
143
 
@@ -158,7 +158,7 @@ def report_source_tool(drug_name: str):
158
  MCP Tool: Creates a pie chart of report sources for a given drug.
159
 
160
  Args:
161
- drug_name (str): The name of the drug.
162
 
163
  Returns:
164
  A Plotly figure.
 
39
  MCP Tool: Finds the top reported adverse events for a given drug.
40
 
41
  Args:
42
+ drug_name (str): The generic name of the drug is preferred! A small sample of brand names (e.g., 'Tylenol') are converted to generic names for demonstration purposes.
43
  patient_sex (str): The patient's sex to filter by.
44
  min_age (int): The minimum age for the filter.
45
  max_age (int): The maximum age for the filter.
 
91
  MCP Tool: Finds the top reported serious outcomes for a given drug.
92
 
93
  Args:
94
+ drug_name (str): The generic name of the drug is preferred. A small sample of brand names (e.g., 'Tylenol') are converted to generic names for demonstration purposes.
95
 
96
  Returns:
97
  tuple: A Plotly figure, a Pandas DataFrame, and a summary string.
 
123
  MCP Tool: Gets the total number of reports for a specific drug and adverse event pair.
124
 
125
  Args:
126
+ drug_name (str): The generic name of the drug is preferred. A small sample of brand names (e.g., 'Tylenol') are converted to generic names for demonstration purposes.
127
  event_name (str): The name of the adverse event to search for.
128
 
129
  Returns:
 
137
  MCP Tool: Creates a time-series plot for a drug-event pair.
138
 
139
  Args:
140
+ drug_name (str): The generic name of the drug is preferred. A small sample of brand names (e.g., 'Tylenol') are converted to generic names for demonstration purposes.
141
  event_name (str): The name of the adverse event.
142
  aggregation (str): Time aggregation ('Yearly' or 'Quarterly').
143
 
 
158
  MCP Tool: Creates a pie chart of report sources for a given drug.
159
 
160
  Args:
161
+ drug_name (str): The generic name of the drug is preferred. A small sample of brand names (e.g., 'Tylenol') are converted to generic names for demonstration purposes.
162
 
163
  Returns:
164
  A Plotly figure.
openfda_client.py CHANGED
@@ -108,13 +108,20 @@ DRUG_SYNONYM_MAPPING = {
108
  }
109
 
110
  OUTCOME_MAPPING = {
111
- "1": "Life-Threatening",
112
- "2": "Hospitalization - Initial or Prolonged",
113
- "3": "Disability",
114
- "4": "Congenital Anomaly",
115
- "5": "Required Intervention to Prevent Permanent Impairment/Damage",
116
- "6": "Death",
117
- "7": "Other Serious (Important Medical Event)",
 
 
 
 
 
 
 
118
  }
119
 
120
  def get_top_adverse_events(drug_name: str, limit: int = 10, patient_sex: Optional[str] = None, age_range: Optional[Tuple[int, int]] = None) -> dict:
@@ -153,8 +160,8 @@ def get_top_adverse_events(drug_name: str, limit: int = 10, patient_sex: Optiona
153
  return cache[cache_key]
154
 
155
  query = (
156
- f'search={search_query}'
157
- f'&count=patient.reaction.reactionmeddrapt.exact&limit={limit}'
158
  )
159
 
160
  try:
@@ -165,6 +172,12 @@ def get_top_adverse_events(drug_name: str, limit: int = 10, patient_sex: Optiona
165
  response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
166
 
167
  data = response.json()
 
 
 
 
 
 
168
  cache[cache_key] = data
169
  return data
170
 
@@ -345,7 +358,7 @@ def get_report_source_data(drug_name: str) -> dict:
345
 
346
  query = (
347
  f'search=patient.drug.medicinalproduct:"{drug_name_processed}"'
348
- f'&count=qualification.exact&limit=5'
349
  )
350
 
351
  try:
@@ -356,6 +369,7 @@ def get_report_source_data(drug_name: str) -> dict:
356
 
357
  data = response.json()
358
 
 
359
  if "results" in data:
360
  for item in data["results"]:
361
  item["term"] = QUALIFICATION_MAPPING.get(item["term"], f"Unknown ({item['term']})")
@@ -370,12 +384,4 @@ def get_report_source_data(drug_name: str) -> dict:
370
  except requests.exceptions.RequestException as req_err:
371
  return {"error": f"A network request error occurred: {req_err}"}
372
  except Exception as e:
373
- return {"error": f"An unexpected error occurred: {e}"}
374
-
375
- QUALIFICATION_MAPPING = {
376
- "1": "Physician",
377
- "2": "Pharmacist",
378
- "3": "Other Health Professional",
379
- "4": "Lawyer",
380
- "5": "Consumer or non-health professional",
381
- }
 
108
  }
109
 
110
  OUTCOME_MAPPING = {
111
+ "1": "Recovered/Resolved",
112
+ "2": "Recovering/Resolving",
113
+ "3": "Not Recovered/Not Resolved",
114
+ "4": "Recovered/Resolved with Sequelae",
115
+ "5": "Fatal",
116
+ "6": "Unknown",
117
+ }
118
+
119
+ QUALIFICATION_MAPPING = {
120
+ "1": "Physician",
121
+ "2": "Pharmacist",
122
+ "3": "Other Health Professional",
123
+ "4": "Lawyer",
124
+ "5": "Consumer or Non-Health Professional",
125
  }
126
 
127
  def get_top_adverse_events(drug_name: str, limit: int = 10, patient_sex: Optional[str] = None, age_range: Optional[Tuple[int, int]] = None) -> dict:
 
160
  return cache[cache_key]
161
 
162
  query = (
163
+ f'search=patient.drug.medicinalproduct:"{drug_name_processed}"'
164
+ f'&count=patient.reaction.reactionoutcome.exact&limit={limit}'
165
  )
166
 
167
  try:
 
172
  response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
173
 
174
  data = response.json()
175
+
176
+ # Translate the outcome codes to human-readable terms
177
+ if "results" in data:
178
+ for item in data["results"]:
179
+ item["term"] = OUTCOME_MAPPING.get(item["term"], f"Unknown ({item['term']})")
180
+
181
  cache[cache_key] = data
182
  return data
183
 
 
358
 
359
  query = (
360
  f'search=patient.drug.medicinalproduct:"{drug_name_processed}"'
361
+ f'&count=primarysource.qualification.exact&limit=5'
362
  )
363
 
364
  try:
 
369
 
370
  data = response.json()
371
 
372
+ # Translate the qualification codes to human-readable terms
373
  if "results" in data:
374
  for item in data["results"]:
375
  item["term"] = QUALIFICATION_MAPPING.get(item["term"], f"Unknown ({item['term']})")
 
384
  except requests.exceptions.RequestException as req_err:
385
  return {"error": f"A network request error occurred: {req_err}"}
386
  except Exception as e:
387
+ return {"error": f"An unexpected error occurred: {e}"}