Skip to main content

Automated Polypharmacy Review: Catching Drug Interactions Across Multi Drug Regimens

· 4 min read
Nikhil Kunche
Founder, Aethryva Deeptech

A patient on 5 drugs has 10 possible pairwise interactions. A patient on 8 drugs has 28. A patient on 12 drugs has 66. The formula is n*(n-1)/2, and it grows fast.

Nobody checks all of them manually. Clinical pharmacists performing medication reconciliation focus on the drugs they know are dangerous together and rely on memory for the rest. That's where things get missed.

Here is a script that takes a medication list and checks every pair, generates a severity matrix, and identifies which drugs need renal or hepatic dose adjustment.

The Tool

pip install moisscode
from moisscode.modules.med_pk import PharmacokineticEngine
from moisscode.modules.med_lab import LabEngine


def polypharmacy_audit(drug_list, creatinine=None, age=None, sex="M"):
"""
Audit a multi-drug regimen for interactions and dosing issues.
Returns interaction matrix, flagged combos, and adjustment needs.
"""
pk = PharmacokineticEngine()
lab = LabEngine()

n = len(drug_list)
total_pairs = n * (n - 1) // 2
interactions_found = []
matrix = {}

# Check all pairwise interactions
for i, drug_a in enumerate(drug_list):
for drug_b in drug_list[i + 1:]:
result = pk.check_interactions(drug_a, [drug_b])
ix_list = result.get("interactions", [])
if ix_list:
sev = result["max_severity"]
safe = result["safe_to_administer"]
interactions_found.append({
"pair": f"{drug_a} x {drug_b}",
"severity": sev,
"safe": safe,
})
matrix[(drug_a, drug_b)] = sev
else:
matrix[(drug_a, drug_b)] = "OK"

# Check renal adjustments if creatinine is provided
adjustments = []
egfr = None
if creatinine and age:
gfr_result = lab.gfr(creatinine=creatinine, age=age, sex=sex)
egfr = gfr_result["eGFR"]
for drug in drug_list:
renal = pk.renal_adjust(drug, gfr=egfr)
if renal["adjustment_factor"] < 1.0:
adjustments.append({
"drug": drug,
"factor": renal["adjustment_factor"],
"recommendation": renal["recommendation"],
})

return {
"drug_count": n,
"pairs_checked": total_pairs,
"interactions": interactions_found,
"interaction_count": len(interactions_found),
"adjustments": adjustments,
"eGFR": egfr,
}

Test Case: An 8 Drug Cardiac Regimen

A 68 year old patient on anticoagulation, antiarrhythmic, antihypertensive, lipid lowering, antiplatelet, and GI protection. This is a normal cardiac outpatient regimen. Nothing exotic.

drugs = [
"Warfarin",
"Amiodarone",
"Metformin",
"Lisinopril",
"Omeprazole",
"Clopidogrel",
"Atorvastatin",
"Amlodipine",
]

result = polypharmacy_audit(drugs, creatinine=1.8, age=68, sex="M")

print(f"Drugs: {result['drug_count']}")
print(f"Pairs checked: {result['pairs_checked']}")
print(f"Interactions found: {result['interaction_count']}")
print(f"eGFR: {result['eGFR']} mL/min")

print("\nFlagged Interactions:")
for ix in result["interactions"]:
print(f" {ix['pair']}: {ix['severity']} (safe={ix['safe']})")

print("\nRenal Adjustments Needed:")
for adj in result["adjustments"]:
print(f" {adj['drug']}: {adj['recommendation']}")

Output:

Drugs: 8
Pairs checked: 28
Interactions found: 2
eGFR: 39.7 mL/min

Flagged Interactions:
Warfarin x Amiodarone: SEVERE (safe=False)
Omeprazole x Clopidogrel: MAJOR (safe=False)

Renal Adjustments Needed:
Metformin: Reduce dose by 50%, monitor closely

28 pairs checked. Two dangerous combinations caught:

  1. Warfarin and Amiodarone: SEVERE. Amiodarone inhibits CYP2C9 and CYP3A4, dramatically increasing warfarin levels. INR can double or triple. This combination requires a 30 to 50% warfarin dose reduction and frequent INR monitoring. It's one of the most dangerous drug combinations in cardiology.

  2. Omeprazole and Clopidogrel: MAJOR. Omeprazole inhibits CYP2C19, which is the enzyme that converts clopidogrel to its active metabolite. The antiplatelet effect is significantly reduced. For post stent patients, this means increased risk of stent thrombosis. The FDA issued a specific warning about this combination.

And a renal adjustment: Metformin needs dose reduction at eGFR 39.7. Below 30, metformin is traditionally contraindicated due to lactic acidosis risk.

Scaling This

For a hospital pharmacy department running daily medication reviews:

# Audit multiple patients
patient_regimens = [
{"id": "PT001", "drugs": ["Warfarin", "Amiodarone", "Metformin"],
"cr": 1.8, "age": 68, "sex": "M"},
{"id": "PT002", "drugs": ["Omeprazole", "Clopidogrel", "Aspirin", "Atorvastatin"],
"cr": 1.0, "age": 55, "sex": "F"},
{"id": "PT003", "drugs": ["Vancomycin", "Gentamicin", "Meropenem", "Fluconazole"],
"cr": 3.2, "age": 45, "sex": "M"},
]

for pt in patient_regimens:
audit = polypharmacy_audit(
pt["drugs"], creatinine=pt["cr"], age=pt["age"], sex=pt["sex"]
)
flag = "⚠" if audit["interaction_count"] > 0 else "✓"
print(f"{flag} {pt['id']}: {audit['interaction_count']} interactions, "
f"eGFR {audit['eGFR']}, "
f"{len(audit['adjustments'])} drugs need adjustment")

The underlying PK engine has 106 drugs with interaction maps. The interaction database covers combinations documented in clinical pharmacology references. Custom drugs can be registered using pk.register_drug() with a DrugProfile dataclass that includes an interactions dict.

Professional biomedical software. All clinical outputs should be validated by qualified professionals before patient care application.

PK Module Documentation | GitHub