# utils/oneclick.py from typing import Tuple, Optional, Dict from .meldrx import MeldRxAPI from .responseparser import PatientDataExtractor from .pdfutils import PDFGenerator import logging from huggingface_hub import InferenceClient logger = logging.getLogger(__name__) HF_TOKEN = os.getenv("HF_TOKEN") if not HF_TOKEN: raise ValueError("HF_TOKEN environment variable not set.") client = InferenceClient(api_key=HF_TOKEN)client = InferenceClient() # Initialize the xAI client (adjust initialization as needed) MODEL_NAME = "meta-llama/Llama-3.3-70B-Instruct" def generate_ai_discharge_summary(patient_dict: Dict[str, str]) -> Optional[str]: """Generate a discharge summary using AI based on extracted patient data.""" try: # Use the formatted summary as input formatted_summary = format_discharge_summary(patient_dict) logger.info("Generating AI discharge summary with patient info: %s", formatted_summary) messages = [ { "role": "assistant", "content": ( "You are a senior medical practitioner tasked with creating discharge summaries. " "Generate a complete discharge summary based on the provided patient information." ) }, {"role": "user", "content": formatted_summary} ] stream = client.chat.completions.create( model=MODEL_NAME, messages=messages, temperature=0.4, max_tokens=3584, top_p=0.7, stream=True ) discharge_summary = "" for chunk in stream: content = chunk.choices[0].delta.content if content: discharge_summary += content logger.info("AI discharge summary generated successfully") return discharge_summary.strip() except Exception as e: logger.error(f"Error generating AI discharge summary: {str(e)}", exc_info=True) return None def generate_discharge_paper_one_click( api: MeldRxAPI, patient_id: str = "", first_name: str = "", last_name: str = "" ) -> Tuple[Optional[str], str, Optional[str], Optional[str]]: """ Generate a discharge summary PDF with one click using MeldRx API data. Returns: Tuple of (pdf_path, status_message, basic_summary, ai_summary) """ try: patients_data = api.get_patients() if not patients_data or "entry" not in patients_data: return None, "Failed to fetch patient data from MeldRx API", None, None extractor = PatientDataExtractor(patients_data, "json") if not extractor.patients: return None, "No patients found in the data", None, None matching_patients = [] for i in range(len(extractor.patients)): extractor.set_patient_by_index(i) patient_data = extractor.get_patient_dict() patient_data.setdefault('id', 'unknown') patient_data.setdefault('first_name', '') patient_data.setdefault('last_name', '') if (not patient_id or patient_data.get("id", "") == patient_id) and \ (not first_name or patient_data.get("first_name", "").lower() == first_name.lower()) and \ (not last_name or patient_data.get("last_name", "").lower() == last_name.lower()): matching_patients.append(patient_data) if not matching_patients: return None, "No matching patients found with the provided criteria", None, None patient_data = matching_patients[0] extractor.set_patient_by_index(0) # Generate both basic and AI summaries basic_summary = format_discharge_summary(patient_data) ai_summary = generate_ai_discharge_summary(patient_data) if not ai_summary: return None, "Failed to generate AI summary", basic_summary, None pdf_gen = PDFGenerator() filename = f"discharge_{patient_data.get('id', 'unknown')}_{patient_data.get('last_name', 'patient')}.pdf" pdf_path = pdf_gen.generate_pdf_from_text(ai_summary, filename) if pdf_path: return pdf_path, "Discharge summary generated successfully", basic_summary, ai_summary return None, "Failed to generate PDF file", basic_summary, ai_summary except Exception as e: logger.error(f"Error in one-click discharge generation: {str(e)}", exc_info=True) return None, f"Error generating discharge summary: {str(e)}", None, None def format_discharge_summary(patient_data: dict) -> str: """Format patient data into a discharge summary text.""" patient_data.setdefault('name_prefix', '') patient_data.setdefault('first_name', '') patient_data.setdefault('last_name', '') patient_data.setdefault('dob', 'Unknown') patient_data.setdefault('age', 'Unknown') patient_data.setdefault('sex', 'Unknown') patient_data.setdefault('id', 'Unknown') patient_data.setdefault('address', 'Unknown') patient_data.setdefault('city', 'Unknown') patient_data.setdefault('state', 'Unknown') patient_data.setdefault('zip_code', 'Unknown') patient_data.setdefault('phone', 'Unknown') patient_data.setdefault('admission_date', 'Unknown') patient_data.setdefault('discharge_date', 'Unknown') patient_data.setdefault('diagnosis', 'Unknown') patient_data.setdefault('medications', 'None specified') patient_data.setdefault('doctor_first_name', 'Unknown') patient_data.setdefault('doctor_last_name', 'Unknown') patient_data.setdefault('hospital_name', 'Unknown') patient_data.setdefault('doctor_address', 'Unknown') patient_data.setdefault('doctor_city', 'Unknown') patient_data.setdefault('doctor_state', 'Unknown') patient_data.setdefault('doctor_zip', 'Unknown') summary = [ "DISCHARGE SUMMARY", "", "PATIENT INFORMATION", f"Name: {patient_data['name_prefix']} {patient_data['first_name']} {patient_data['last_name']}".strip(), f"Date of Birth: {patient_data['dob']}", f"Age: {patient_data['age']}", f"Gender: {patient_data['sex']}", f"Patient ID: {patient_data['id']}", "", "CONTACT INFORMATION", f"Address: {patient_data['address']}", f"City: {patient_data['city']}, {patient_data['state']} {patient_data['zip_code']}", f"Phone: {patient_data['phone']}", "", "ADMISSION INFORMATION", f"Admission Date: {patient_data['admission_date']}", f"Discharge Date: {patient_data['discharge_date']}", f"Diagnosis: {patient_data['diagnosis']}", "", "MEDICATIONS", f"{patient_data['medications']}", "", "PHYSICIAN INFORMATION", f"Physician: Dr. {patient_data['doctor_first_name']} {patient_data['doctor_last_name']}".strip(), f"Hospital: {patient_data['hospital_name']}", f"Address: {patient_data['doctor_address']}", f"City: {patient_data['doctor_city']}, {patient_data['doctor_state']} {patient_data['doctor_zip']}", ] return "\n".join(line for line in summary if line.strip() or line == "")