Med-X_25.10.8 / pharmaceutical_database.py
DeepRat's picture
Upload 43 files
64eded8 verified
#!/usr/bin/env python3
"""
💊 PHARMACEUTICAL DATABASE SYSTEM (Micromedex-style)
Base de datos farmacéutica completa integrada con RAG
📋 CARACTERÍSTICAS:
✅ Monografías completas de medicamentos
✅ Interacciones medicamentosas
✅ Dosificación por edad/peso/patología
✅ Efectos adversos y contraindicaciones
✅ Compatibilidad IV
✅ Farmacocinética y farmacodinamia
✅ Equivalencias terapéuticas
✅ Alertas de seguridad
"""
from dataclasses import dataclass
from typing import Dict, List, Any, Optional, Tuple
from enum import Enum
import json
from pathlib import Path
class InteractionSeverity(Enum):
MINOR = "minor"
MODERATE = "moderate"
MAJOR = "major"
CONTRAINDICATED = "contraindicated"
class RouteOfAdministration(Enum):
ORAL = "oral"
IV = "intravenous"
IM = "intramuscular"
SC = "subcutaneous"
TOPICAL = "topical"
INHALATION = "inhalation"
RECTAL = "rectal"
SUBLINGUAL = "sublingual"
@dataclass
class DrugInteraction:
"""Interacción medicamentosa"""
drug_a: str
drug_b: str
severity: InteractionSeverity
mechanism: str
clinical_effect: str
management: str
onset: str # rapid, delayed
documentation: str # excellent, good, fair, poor
@dataclass
class Dosage:
"""Dosificación por condición específica"""
indication: str
adult_dose: str
pediatric_dose: Optional[str]
elderly_dose: Optional[str]
renal_adjustment: Optional[str]
hepatic_adjustment: Optional[str]
route: RouteOfAdministration
frequency: str
duration: Optional[str]
max_dose: Optional[str]
@dataclass
class AdverseEffect:
"""Efecto adverso"""
effect: str
frequency: str # very_common, common, uncommon, rare, very_rare
severity: str # mild, moderate, severe, life_threatening
onset: str # immediate, early, delayed
reversible: bool
monitoring_required: bool
@dataclass
class Contraindication:
"""Contraindicación"""
condition: str
severity: str # absolute, relative
reason: str
@dataclass
class PharmacokineticData:
"""Datos farmacocinéticos"""
absorption: str
distribution: str
metabolism: str
elimination: str
half_life: str
bioavailability: Optional[str]
protein_binding: Optional[str]
clearance: Optional[str]
@dataclass
class DrugMonograph:
"""Monografía completa de medicamento"""
name: str
generic_name: str
brand_names: List[str]
drug_class: str
therapeutic_category: str
mechanism_of_action: str
indications: List[str]
dosages: List[Dosage]
contraindications: List[Contraindication]
adverse_effects: List[AdverseEffect]
pharmacokinetics: PharmacokineticData
monitoring_parameters: List[str]
patient_counseling: List[str]
storage_conditions: str
pregnancy_category: str
lactation_safety: str
pediatric_use: str
geriatric_use: str
cost_effectiveness: Optional[str]
class PharmaceuticalDatabase:
"""Base de datos farmacéutica completa tipo Micromedex"""
def __init__(self):
self.monographs: Dict[str, DrugMonograph] = {}
self.interactions: List[DrugInteraction] = []
self.compatibility_matrix: Dict[str, Dict[str, str]] = {}
self._initialize_database()
print("💊 Base de datos farmacéutica inicializada")
def _initialize_database(self):
"""Inicializa la base de datos con medicamentos esenciales"""
# Aspirina - Antiagregante plaquetario
aspirin_monograph = DrugMonograph(
name="Aspirina",
generic_name="Ácido acetilsalicílico",
brand_names=["Aspirina", "AAS", "Aspegic", "Cardioaspirina"],
drug_class="AINE - Antiagregante plaquetario",
therapeutic_category="Cardiovascular/Analgésico",
mechanism_of_action="Inhibición irreversible de COX-1 y COX-2, bloqueando síntesis de tromboxano A2",
indications=[
"Prevención cardiovascular primaria y secundaria",
"Síndrome coronario agudo",
"Dolor leve a moderado",
"Fiebre",
"Artritis reumatoide"
],
dosages=[
Dosage(
indication="Prevención cardiovascular",
adult_dose="75-100 mg",
pediatric_dose="No recomendado < 16 años (Síndrome de Reye)",
elderly_dose="75 mg (ajustar por sangrado)",
renal_adjustment="Evitar si ClCr < 30 mL/min",
hepatic_adjustment="Evitar en insuficiencia hepática severa",
route=RouteOfAdministration.ORAL,
frequency="Una vez al día",
duration="Indefinido si no hay contraindicaciones",
max_dose="100 mg/día para cardioprotección"
),
Dosage(
indication="Síndrome coronario agudo",
adult_dose="150-300 mg dosis carga, luego 75-100 mg",
pediatric_dose="No aplicable",
elderly_dose="75-100 mg",
renal_adjustment="Monitorear función renal",
hepatic_adjustment="Precaución",
route=RouteOfAdministration.ORAL,
frequency="Dosis carga única, luego diario",
duration="Indefinido",
max_dose="300 mg dosis carga"
)
],
contraindications=[
Contraindication("Alergia a salicilatos", "absolute", "Riesgo anafilaxia"),
Contraindication("Sangrado activo", "absolute", "Antiagregación"),
Contraindication("Úlcera péptica activa", "absolute", "Riesgo hemorragia"),
Contraindication("Asma inducida por AINE", "absolute", "Broncoespasmo severo"),
Contraindication("Niños < 16 años con fiebre", "absolute", "Síndrome de Reye")
],
adverse_effects=[
AdverseEffect("Dispepsia", "common", "mild", "early", True, False),
AdverseEffect("Sangrado gastrointestinal", "uncommon", "severe", "variable", False, True),
AdverseEffect("Tinnitus", "uncommon", "moderate", "delayed", True, False),
AdverseEffect("Reacciones de hipersensibilidad", "rare", "severe", "immediate", True, True)
],
pharmacokinetics=PharmacokineticData(
absorption="Rápida y completa, 80-100%",
distribution="Amplia, atraviesa BHE y placenta",
metabolism="Hepático (conjugación)",
elimination="Renal 95%",
half_life="15-30 min (dosis bajas), 4-6 h (dosis altas)",
bioavailability="80-100%",
protein_binding="80-90%",
clearance="Dependiente de dosis"
),
monitoring_parameters=[
"Función renal",
"Signos de sangrado",
"Hemograma",
"Función hepática"
],
patient_counseling=[
"Tomar con alimentos para reducir irritación gástrica",
"Reportar sangrados inusuales",
"No suspender abruptamente si uso cardiovascular",
"Evitar alcohol excesivo"
],
storage_conditions="Temperatura ambiente, proteger de humedad",
pregnancy_category="D (tercer trimestre)",
lactation_safety="Compatible en dosis bajas",
pediatric_use="Contraindicado < 16 años por Síndrome de Reye",
geriatric_use="Aumentar monitoreo por riesgo sangrado",
cost_effectiveness="Excelente para prevención cardiovascular"
)
# Metformina - Antidiabético
metformin_monograph = DrugMonograph(
name="Metformina",
generic_name="Metformina clorhidrato",
brand_names=["Glucophage", "Glafornil", "Metformina"],
drug_class="Biguanida",
therapeutic_category="Antidiabético oral",
mechanism_of_action="Reduce gluconeogénesis hepática, aumenta sensibilidad a insulina",
indications=[
"Diabetes mellitus tipo 2",
"Prediabetes",
"Síndrome de ovario poliquístico",
"Resistencia a insulina"
],
dosages=[
Dosage(
indication="Diabetes tipo 2",
adult_dose="500 mg BID, incrementar cada semana",
pediatric_dose="500 mg BID > 10 años",
elderly_dose="Iniciar 500 mg/día, ajustar por función renal",
renal_adjustment="Evitar si eGFR < 30 mL/min/1.73m²",
hepatic_adjustment="Evitar en insuficiencia hepática",
route=RouteOfAdministration.ORAL,
frequency="2-3 veces al día",
duration="Indefinido",
max_dose="2550 mg/día"
)
],
contraindications=[
Contraindication("eGFR < 30 mL/min/1.73m²", "absolute", "Riesgo acidosis láctica"),
Contraindication("Acidosis metabólica", "absolute", "Empeora acidosis"),
Contraindication("Insuficiencia hepática", "absolute", "Metabolismo lactato"),
Contraindication("Insuficiencia cardíaca descompensada", "absolute", "Hipoxia tisular")
],
adverse_effects=[
AdverseEffect("Diarrea", "very_common", "mild", "early", True, False),
AdverseEffect("Náuseas", "very_common", "mild", "early", True, False),
AdverseEffect("Dolor abdominal", "common", "mild", "early", True, False),
AdverseEffect("Acidosis láctica", "very_rare", "life_threatening", "variable", False, True),
AdverseEffect("Deficiencia B12", "uncommon", "moderate", "delayed", True, True)
],
pharmacokinetics=PharmacokineticData(
absorption="50-60% biodisponibilidad oral",
distribution="No se une a proteínas plasmáticas",
metabolism="No metabolizada",
elimination="Renal 90% sin cambios",
half_life="4-9 horas",
bioavailability="50-60%",
protein_binding="0%",
clearance="Renal activo"
),
monitoring_parameters=[
"HbA1c",
"Función renal (eGFR)",
"Vitamina B12",
"Función hepática",
"Lactato (si sospecha acidosis)"
],
patient_counseling=[
"Tomar con comidas para reducir efectos GI",
"No suspender sin consultar",
"Reconocer síntomas de acidosis láctica",
"Suspender antes de procedimientos con contraste"
],
storage_conditions="Temperatura ambiente",
pregnancy_category="B",
lactation_safety="Compatible",
pediatric_use="Seguro > 10 años",
geriatric_use="Ajustar por función renal",
cost_effectiveness="Excelente, primera línea en DM2"
)
# Atorvastatina - Estatina
atorvastatin_monograph = DrugMonograph(
name="Atorvastatina",
generic_name="Atorvastatina cálcica",
brand_names=["Lipitor", "Zarator", "Atorvastatina"],
drug_class="Inhibidor HMG-CoA reductasa (Estatina)",
therapeutic_category="Hipolipemiante",
mechanism_of_action="Inhibición competitiva HMG-CoA reductasa, reduce síntesis colesterol",
indications=[
"Hipercolesterolemia",
"Prevención cardiovascular primaria",
"Prevención cardiovascular secundaria",
"Dislipidemia familiar"
],
dosages=[
Dosage(
indication="Hipercolesterolemia",
adult_dose="10-20 mg inicial",
pediatric_dose="10 mg > 10 años (hipercolesterolemia familiar)",
elderly_dose="10 mg inicial",
renal_adjustment="No requiere ajuste",
hepatic_adjustment="Contraindicado en hepatopatía activa",
route=RouteOfAdministration.ORAL,
frequency="Una vez al día por la noche",
duration="Indefinido",
max_dose="80 mg/día"
)
],
contraindications=[
Contraindication("Hepatopatía activa", "absolute", "Hepatotoxicidad"),
Contraindication("Embarazo", "absolute", "Teratogenia"),
Contraindication("Lactancia", "absolute", "Paso a leche materna"),
Contraindication("Miopatía activa", "absolute", "Rabdomiólisis")
],
adverse_effects=[
AdverseEffect("Mialgia", "common", "mild", "variable", True, False),
AdverseEffect("Elevación transaminasas", "uncommon", "moderate", "delayed", True, True),
AdverseEffect("Rabdomiólisis", "very_rare", "life_threatening", "variable", False, True),
AdverseEffect("Diabetes de nuevo diagnóstico", "uncommon", "moderate", "delayed", False, True)
],
pharmacokinetics=PharmacokineticData(
absorption="Rápida, baja biodisponibilidad (14%)",
distribution="98% unión proteica",
metabolism="CYP3A4 extenso primer paso",
elimination="Biliar principalmente",
half_life="14 horas",
bioavailability="14%",
protein_binding="98%",
clearance="Hepática"
),
monitoring_parameters=[
"Perfil lipídico",
"Transaminasas",
"CK (si síntomas musculares)",
"HbA1c (riesgo diabetes)"
],
patient_counseling=[
"Tomar por la noche",
"Reportar dolor muscular",
"Seguir dieta cardiosaludable",
"No suspender sin consultar"
],
storage_conditions="Temperatura ambiente",
pregnancy_category="X",
lactation_safety="Contraindicado",
pediatric_use="Hipercolesterolemia familiar > 10 años",
geriatric_use="Mismo perfil de seguridad",
cost_effectiveness="Excelente para prevención cardiovascular"
)
# Registrar monografías
self.monographs["aspirina"] = aspirin_monograph
self.monographs["metformina"] = metformin_monograph
self.monographs["atorvastatina"] = atorvastatin_monograph
# Interacciones importantes
self.interactions = [
DrugInteraction(
drug_a="aspirina",
drug_b="warfarina",
severity=InteractionSeverity.MAJOR,
mechanism="Antiagregación sinérgica + anticoagulación",
clinical_effect="Aumento significativo riesgo sangrado",
management="Evitar combinación o monitoreo estrecho INR",
onset="rapid",
documentation="excellent"
),
DrugInteraction(
drug_a="metformina",
drug_b="contraste_iodado",
severity=InteractionSeverity.MAJOR,
mechanism="Nefrotoxicidad del contraste + eliminación renal metformina",
clinical_effect="Riesgo acidosis láctica por acumulación",
management="Suspender metformina 48h antes y después del contraste",
onset="delayed",
documentation="excellent"
),
DrugInteraction(
drug_a="atorvastatina",
drug_b="ciclosporina",
severity=InteractionSeverity.MAJOR,
mechanism="Inhibición CYP3A4 por ciclosporina",
clinical_effect="Aumento concentraciones atorvastatina, riesgo miopatía",
management="Reducir dosis atorvastatina o cambiar estatina",
onset="delayed",
documentation="excellent"
)
]
# Matriz de compatibilidad IV (ejemplos)
self.compatibility_matrix = {
"furosemida": {
"aminofilina": "incompatible",
"dexametasona": "compatible",
"heparina": "compatible",
"insulina": "compatible"
},
"heparina": {
"furosemida": "compatible",
"diazepam": "incompatible",
"morfina": "compatible"
}
}
def search_drug(self, drug_name: str) -> Optional[DrugMonograph]:
"""Busca medicamento por nombre"""
drug_lower = drug_name.lower()
# Búsqueda directa
if drug_lower in self.monographs:
return self.monographs[drug_lower]
# Búsqueda por nombre genérico o marca
for monograph in self.monographs.values():
if (drug_lower in monograph.generic_name.lower() or
any(drug_lower in brand.lower() for brand in monograph.brand_names)):
return monograph
return None
def check_interactions(self, drug_list: List[str]) -> List[DrugInteraction]:
"""Verifica interacciones entre lista de medicamentos"""
interactions_found = []
for i, drug_a in enumerate(drug_list):
for drug_b in drug_list[i+1:]:
for interaction in self.interactions:
if ((interaction.drug_a.lower() == drug_a.lower() and
interaction.drug_b.lower() == drug_b.lower()) or
(interaction.drug_a.lower() == drug_b.lower() and
interaction.drug_b.lower() == drug_a.lower())):
interactions_found.append(interaction)
return interactions_found
def get_dosage_recommendation(self, drug_name: str, indication: str,
patient_age: int, weight: Optional[float] = None,
renal_function: Optional[str] = None) -> Optional[str]:
"""Obtiene recomendación de dosificación personalizada"""
monograph = self.search_drug(drug_name)
if not monograph:
return None
# Buscar dosificación para indicación específica
relevant_dosages = [d for d in monograph.dosages
if indication.lower() in d.indication.lower()]
if not relevant_dosages:
relevant_dosages = monograph.dosages
if not relevant_dosages:
return None
dosage = relevant_dosages[0] # Tomar primera coincidencia
# Determinar dosis según edad
if patient_age < 18 and dosage.pediatric_dose:
base_dose = dosage.pediatric_dose
elif patient_age >= 65 and dosage.elderly_dose:
base_dose = dosage.elderly_dose
else:
base_dose = dosage.adult_dose
recommendation = f"Dosis recomendada: {base_dose}"
recommendation += f"\nVía: {dosage.route.value}"
recommendation += f"\nFrecuencia: {dosage.frequency}"
if dosage.duration:
recommendation += f"\nDuración: {dosage.duration}"
# Ajustes especiales
if renal_function and renal_function.lower() in ["reducida", "insuficiente"]:
if dosage.renal_adjustment:
recommendation += f"\nAjuste renal: {dosage.renal_adjustment}"
return recommendation
def get_safety_alerts(self, drug_name: str, patient_conditions: List[str]) -> List[str]:
"""Obtiene alertas de seguridad para condiciones del paciente"""
monograph = self.search_drug(drug_name)
if not monograph:
return []
alerts = []
# Verificar contraindicaciones
for contraindication in monograph.contraindications:
for condition in patient_conditions:
if condition.lower() in contraindication.condition.lower():
severity_text = "⚠️ ALERTA" if contraindication.severity == "relative" else "🚨 CONTRAINDICACIÓN ABSOLUTA"
alerts.append(f"{severity_text}: {contraindication.condition} - {contraindication.reason}")
# Efectos adversos graves
serious_effects = [ae for ae in monograph.adverse_effects
if ae.severity in ["severe", "life_threatening"]]
if serious_effects:
alerts.append(f"⚠️ Monitorear: {', '.join([ae.effect for ae in serious_effects])}")
return alerts
def check_iv_compatibility(self, drug_a: str, drug_b: str) -> Optional[str]:
"""Verifica compatibilidad IV entre dos medicamentos"""
drug_a_lower = drug_a.lower()
drug_b_lower = drug_b.lower()
if drug_a_lower in self.compatibility_matrix:
return self.compatibility_matrix[drug_a_lower].get(drug_b_lower)
elif drug_b_lower in self.compatibility_matrix:
return self.compatibility_matrix[drug_b_lower].get(drug_a_lower)
return None
def generate_pharmaceutical_context(self, query: str) -> str:
"""Genera contexto farmacéutico para RAG"""
query_lower = query.lower()
context_parts = []
# Buscar medicamentos mencionados
for drug_name, monograph in self.monographs.items():
if (drug_name in query_lower or
monograph.generic_name.lower() in query_lower or
any(brand.lower() in query_lower for brand in monograph.brand_names)):
context_parts.append(f"MEDICAMENTO: {monograph.name}")
context_parts.append(f"Clase: {monograph.drug_class}")
context_parts.append(f"Indicaciones: {', '.join(monograph.indications[:3])}")
if monograph.dosages:
context_parts.append(f"Dosis típica: {monograph.dosages[0].adult_dose}")
# Contraindicaciones importantes
major_contraindications = [c.condition for c in monograph.contraindications
if c.severity == "absolute"]
if major_contraindications:
context_parts.append(f"Contraindicaciones: {', '.join(major_contraindications[:2])}")
context_parts.append("---")
# Agregar alertas de interacciones si se mencionan múltiples medicamentos
mentioned_drugs = []
for drug_name in self.monographs.keys():
if drug_name in query_lower:
mentioned_drugs.append(drug_name)
if len(mentioned_drugs) > 1:
interactions = self.check_interactions(mentioned_drugs)
if interactions:
context_parts.append("INTERACCIONES DETECTADAS:")
for interaction in interactions[:2]: # Máximo 2
context_parts.append(f"⚠️ {interaction.drug_a} + {interaction.drug_b}: {interaction.clinical_effect}")
return "\n".join(context_parts) if context_parts else ""
if __name__ == "__main__":
# Demo del sistema farmacéutico
pharma_db = PharmaceuticalDatabase()
print("💊 DEMO BASE DE DATOS FARMACÉUTICA")
print("=" * 40)
# Buscar medicamento
aspirin = pharma_db.search_drug("aspirina")
if aspirin:
print(f"✅ Encontrado: {aspirin.name}")
print(f"Clase: {aspirin.drug_class}")
print(f"Indicaciones: {len(aspirin.indications)}")
# Verificar interacciones
interactions = pharma_db.check_interactions(["aspirina", "warfarina"])
print(f"🔍 Interacciones encontradas: {len(interactions)}")
# Generar contexto
context = pharma_db.generate_pharmaceutical_context("paciente diabético toma metformina")
print(f"🧠 Contexto generado: {len(context)} caracteres")
print("\n✅ Sistema farmacéutico operativo")