Spaces:
Sleeping
Sleeping
| #!/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" | |
| 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 | |
| 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] | |
| 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 | |
| class Contraindication: | |
| """Contraindicación""" | |
| condition: str | |
| severity: str # absolute, relative | |
| reason: str | |
| 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] | |
| 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") |