fix generation parameters
Browse files- app.py +118 -4
- utils/oneclick.py +35 -21
app.py
CHANGED
|
@@ -64,15 +64,20 @@ def one_click():
|
|
| 64 |
last_name = request.form.get('last_name', '').strip()
|
| 65 |
action = request.form.get('action', '')
|
| 66 |
|
|
|
|
|
|
|
| 67 |
pdf_path, status, basic_summary, ai_summary = generate_discharge_paper_one_click(
|
| 68 |
-
meldrx_api, patient_id, first_name, last_name
|
| 69 |
)
|
| 70 |
|
| 71 |
if action == "Display Summary":
|
| 72 |
return render_template('oneclick.html',
|
| 73 |
status=status,
|
| 74 |
basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 75 |
-
ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None
|
|
|
|
|
|
|
|
|
|
| 76 |
elif action == "Generate PDF" and pdf_path:
|
| 77 |
return send_file(pdf_path,
|
| 78 |
as_attachment=True,
|
|
@@ -80,10 +85,119 @@ def one_click():
|
|
| 80 |
return render_template('oneclick.html',
|
| 81 |
status=status,
|
| 82 |
basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 83 |
-
ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
return render_template('oneclick.html')
|
| 86 |
|
| 87 |
if __name__ == '__main__':
|
| 88 |
port = int(os.getenv("PORT", 7860))
|
| 89 |
-
app.run(debug=False, host='0.0.0.0', port=port)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
last_name = request.form.get('last_name', '').strip()
|
| 65 |
action = request.form.get('action', '')
|
| 66 |
|
| 67 |
+
logger.info(f"One-click request - ID: {patient_id}, First: {first_name}, Last: {last_name}, Action: {action}")
|
| 68 |
+
|
| 69 |
pdf_path, status, basic_summary, ai_summary = generate_discharge_paper_one_click(
|
| 70 |
+
meldrx_api, grok_client, patient_id, first_name, last_name
|
| 71 |
)
|
| 72 |
|
| 73 |
if action == "Display Summary":
|
| 74 |
return render_template('oneclick.html',
|
| 75 |
status=status,
|
| 76 |
basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 77 |
+
ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None,
|
| 78 |
+
patient_id=patient_id,
|
| 79 |
+
first_name=first_name,
|
| 80 |
+
last_name=last_name)
|
| 81 |
elif action == "Generate PDF" and pdf_path:
|
| 82 |
return send_file(pdf_path,
|
| 83 |
as_attachment=True,
|
|
|
|
| 85 |
return render_template('oneclick.html',
|
| 86 |
status=status,
|
| 87 |
basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 88 |
+
ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None,
|
| 89 |
+
patient_id=patient_id,
|
| 90 |
+
first_name=first_name,
|
| 91 |
+
last_name=last_name)
|
| 92 |
|
| 93 |
return render_template('oneclick.html')
|
| 94 |
|
| 95 |
if __name__ == '__main__':
|
| 96 |
port = int(os.getenv("PORT", 7860))
|
| 97 |
+
app.run(debug=False, host='0.0.0.0', port=port)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
# # app.py
|
| 102 |
+
# from flask import Flask, render_template, request, send_file, redirect, url_for
|
| 103 |
+
# import os
|
| 104 |
+
# import logging
|
| 105 |
+
# from utils.meldrx import MeldRxAPI
|
| 106 |
+
# from utils.oneclick import generate_discharge_paper_one_click
|
| 107 |
+
# from xai import Grok # Adjust import based on actual xAI SDK
|
| 108 |
+
|
| 109 |
+
# logging.basicConfig(level=logging.DEBUG) # Changed to DEBUG for more detailed logs
|
| 110 |
+
# logger = logging.getLogger(__name__)
|
| 111 |
+
|
| 112 |
+
# app = Flask(__name__)
|
| 113 |
+
|
| 114 |
+
# CLIENT_ID = os.getenv("MELDRX_CLIENT_ID", "04bdc9f9a23d488a868b93d594ee5a4a")
|
| 115 |
+
# CLIENT_SECRET = os.getenv("MELDRX_CLIENT_SECRET", None)
|
| 116 |
+
# WORKSPACE_ID = os.getenv("MELDRX_WORKSPACE_ID", "09ed4f76-b5ac-42bf-92d5-496933203dbe")
|
| 117 |
+
# SPACE_URL = os.getenv("SPACE_URL", "https://multitransformer-tonic-discharge-guard.hf.space")
|
| 118 |
+
# REDIRECT_URI = f"{SPACE_URL}/auth/callback"
|
| 119 |
+
|
| 120 |
+
# meldrx_api = MeldRxAPI(
|
| 121 |
+
# client_id=CLIENT_ID,
|
| 122 |
+
# client_secret=CLIENT_SECRET,
|
| 123 |
+
# workspace_id=WORKSPACE_ID,
|
| 124 |
+
# redirect_uri=REDIRECT_URI
|
| 125 |
+
# )
|
| 126 |
+
|
| 127 |
+
# # Initialize xAI client
|
| 128 |
+
# grok_client = Grok() # Adjust initialization as needed
|
| 129 |
+
|
| 130 |
+
# @app.route('/')
|
| 131 |
+
# def index():
|
| 132 |
+
# return render_template('index.html')
|
| 133 |
+
|
| 134 |
+
# @app.route('/auth', methods=['GET', 'POST'])
|
| 135 |
+
# def auth():
|
| 136 |
+
# if request.method == 'POST':
|
| 137 |
+
# auth_code = request.form.get('auth_code')
|
| 138 |
+
# if auth_code and meldrx_api.authenticate_with_code(auth_code):
|
| 139 |
+
# return redirect(url_for('dashboard'))
|
| 140 |
+
# return render_template('auth.html', auth_url=meldrx_api.get_authorization_url(), auth_result="Authentication failed")
|
| 141 |
+
# return render_template('auth.html', auth_url=meldrx_api.get_authorization_url())
|
| 142 |
+
|
| 143 |
+
# @app.route('/auth/callback', methods=['GET'])
|
| 144 |
+
# def auth_callback():
|
| 145 |
+
# auth_code = request.args.get('code')
|
| 146 |
+
# if auth_code and meldrx_api.authenticate_with_code(auth_code):
|
| 147 |
+
# return redirect(url_for('dashboard'))
|
| 148 |
+
# return render_template('auth.html', auth_url=meldrx_api.get_authorization_url(), auth_result="Callback failed")
|
| 149 |
+
|
| 150 |
+
# @app.route('/dashboard', methods=['GET'])
|
| 151 |
+
# def dashboard():
|
| 152 |
+
# if not meldrx_api.access_token:
|
| 153 |
+
# return redirect(url_for('auth'))
|
| 154 |
+
# patients_data = meldrx_api.get_patients()
|
| 155 |
+
# if not patients_data or "entry" not in patients_data:
|
| 156 |
+
# logger.error("Failed to fetch patient data for dashboard")
|
| 157 |
+
# return render_template('dashboard.html', error="Failed to fetch patient data")
|
| 158 |
+
# patients = [entry['resource'] for entry in patients_data.get('entry', [])]
|
| 159 |
+
# logger.debug(f"Patients for dashboard: {patients}")
|
| 160 |
+
# return render_template('dashboard.html', patients=patients, authenticated=True)
|
| 161 |
+
|
| 162 |
+
# @app.route('/oneclick', methods=['GET', 'POST'])
|
| 163 |
+
# def one_click():
|
| 164 |
+
# if not meldrx_api.access_token:
|
| 165 |
+
# return redirect(url_for('auth'))
|
| 166 |
+
|
| 167 |
+
# if request.method == 'POST':
|
| 168 |
+
# patient_id = request.form.get('patient_id', '').strip()
|
| 169 |
+
# first_name = request.form.get('first_name', '').strip()
|
| 170 |
+
# last_name = request.form.get('last_name', '').strip()
|
| 171 |
+
# action = request.form.get('action', '')
|
| 172 |
+
|
| 173 |
+
# logger.info(f"One-click request - ID: {patient_id}, First: {first_name}, Last: {last_name}, Action: {action}")
|
| 174 |
+
|
| 175 |
+
# pdf_path, status, basic_summary, ai_summary = generate_discharge_paper_one_click(
|
| 176 |
+
# meldrx_api, grok_client, patient_id, first_name, last_name
|
| 177 |
+
# )
|
| 178 |
+
|
| 179 |
+
# if action == "Display Summary":
|
| 180 |
+
# return render_template('oneclick.html',
|
| 181 |
+
# status=status,
|
| 182 |
+
# basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 183 |
+
# ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None,
|
| 184 |
+
# patient_id=patient_id,
|
| 185 |
+
# first_name=first_name,
|
| 186 |
+
# last_name=last_name)
|
| 187 |
+
# elif action == "Generate PDF" and pdf_path:
|
| 188 |
+
# return send_file(pdf_path,
|
| 189 |
+
# as_attachment=True,
|
| 190 |
+
# download_name=f"discharge_summary_{patient_id or 'patient'}.pdf")
|
| 191 |
+
# return render_template('oneclick.html',
|
| 192 |
+
# status=status,
|
| 193 |
+
# basic_summary=basic_summary.replace('\n', '<br>') if basic_summary else None,
|
| 194 |
+
# ai_summary=ai_summary.replace('\n', '<br>') if ai_summary else None,
|
| 195 |
+
# patient_id=patient_id,
|
| 196 |
+
# first_name=first_name,
|
| 197 |
+
# last_name=last_name)
|
| 198 |
+
|
| 199 |
+
# return render_template('oneclick.html')
|
| 200 |
+
|
| 201 |
+
# if __name__ == '__main__':
|
| 202 |
+
# port = int(os.getenv("PORT", 7860))
|
| 203 |
+
# app.run(debug=False, host='0.0.0.0', port=port)
|
utils/oneclick.py
CHANGED
|
@@ -4,21 +4,12 @@ from .meldrx import MeldRxAPI
|
|
| 4 |
from .responseparser import PatientDataExtractor
|
| 5 |
from .pdfutils import PDFGenerator
|
| 6 |
import logging
|
| 7 |
-
from huggingface_hub import InferenceClient
|
| 8 |
-
import os
|
| 9 |
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
| 12 |
-
|
| 13 |
-
if not HF_TOKEN:
|
| 14 |
-
raise ValueError("HF_TOKEN environment variable not set.")
|
| 15 |
-
client = InferenceClient(api_key=HF_TOKEN)
|
| 16 |
-
MODEL_NAME = "meta-llama/Llama-3.3-70B-Instruct"
|
| 17 |
-
|
| 18 |
-
def generate_ai_discharge_summary(patient_dict: Dict[str, str]) -> Optional[str]:
|
| 19 |
"""Generate a discharge summary using AI based on extracted patient data."""
|
| 20 |
try:
|
| 21 |
-
# Use the formatted summary as input
|
| 22 |
formatted_summary = format_discharge_summary(patient_dict)
|
| 23 |
|
| 24 |
logger.info("Generating AI discharge summary with patient info: %s", formatted_summary)
|
|
@@ -35,7 +26,7 @@ def generate_ai_discharge_summary(patient_dict: Dict[str, str]) -> Optional[str]
|
|
| 35 |
]
|
| 36 |
|
| 37 |
stream = client.chat.completions.create(
|
| 38 |
-
model=
|
| 39 |
messages=messages,
|
| 40 |
temperature=0.4,
|
| 41 |
max_tokens=3584,
|
|
@@ -58,6 +49,7 @@ def generate_ai_discharge_summary(patient_dict: Dict[str, str]) -> Optional[str]
|
|
| 58 |
|
| 59 |
def generate_discharge_paper_one_click(
|
| 60 |
api: MeldRxAPI,
|
|
|
|
| 61 |
patient_id: str = "",
|
| 62 |
first_name: str = "",
|
| 63 |
last_name: str = ""
|
|
@@ -71,36 +63,58 @@ def generate_discharge_paper_one_click(
|
|
| 71 |
try:
|
| 72 |
patients_data = api.get_patients()
|
| 73 |
if not patients_data or "entry" not in patients_data:
|
|
|
|
| 74 |
return None, "Failed to fetch patient data from MeldRx API", None, None
|
| 75 |
|
|
|
|
|
|
|
| 76 |
extractor = PatientDataExtractor(patients_data, "json")
|
| 77 |
|
| 78 |
if not extractor.patients:
|
|
|
|
| 79 |
return None, "No patients found in the data", None, None
|
| 80 |
|
|
|
|
|
|
|
| 81 |
matching_patients = []
|
| 82 |
for i in range(len(extractor.patients)):
|
| 83 |
extractor.set_patient_by_index(i)
|
| 84 |
patient_data = extractor.get_patient_dict()
|
| 85 |
|
| 86 |
-
patient_data.
|
| 87 |
-
patient_data.
|
| 88 |
-
patient_data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
matching_patients.append(patient_data)
|
|
|
|
| 94 |
|
| 95 |
if not matching_patients:
|
| 96 |
-
|
|
|
|
|
|
|
| 97 |
|
| 98 |
patient_data = matching_patients[0]
|
| 99 |
-
|
| 100 |
|
| 101 |
-
# Generate both basic and AI summaries
|
| 102 |
basic_summary = format_discharge_summary(patient_data)
|
| 103 |
-
ai_summary = generate_ai_discharge_summary(patient_data)
|
| 104 |
|
| 105 |
if not ai_summary:
|
| 106 |
return None, "Failed to generate AI summary", basic_summary, None
|
|
|
|
| 4 |
from .responseparser import PatientDataExtractor
|
| 5 |
from .pdfutils import PDFGenerator
|
| 6 |
import logging
|
|
|
|
|
|
|
| 7 |
|
| 8 |
logger = logging.getLogger(__name__)
|
| 9 |
|
| 10 |
+
def generate_ai_discharge_summary(patient_dict: Dict[str, str], client) -> Optional[str]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
"""Generate a discharge summary using AI based on extracted patient data."""
|
| 12 |
try:
|
|
|
|
| 13 |
formatted_summary = format_discharge_summary(patient_dict)
|
| 14 |
|
| 15 |
logger.info("Generating AI discharge summary with patient info: %s", formatted_summary)
|
|
|
|
| 26 |
]
|
| 27 |
|
| 28 |
stream = client.chat.completions.create(
|
| 29 |
+
model="grok-3",
|
| 30 |
messages=messages,
|
| 31 |
temperature=0.4,
|
| 32 |
max_tokens=3584,
|
|
|
|
| 49 |
|
| 50 |
def generate_discharge_paper_one_click(
|
| 51 |
api: MeldRxAPI,
|
| 52 |
+
client,
|
| 53 |
patient_id: str = "",
|
| 54 |
first_name: str = "",
|
| 55 |
last_name: str = ""
|
|
|
|
| 63 |
try:
|
| 64 |
patients_data = api.get_patients()
|
| 65 |
if not patients_data or "entry" not in patients_data:
|
| 66 |
+
logger.error("No patient data received from MeldRx API")
|
| 67 |
return None, "Failed to fetch patient data from MeldRx API", None, None
|
| 68 |
|
| 69 |
+
logger.debug(f"Raw patient data from API: {patients_data}")
|
| 70 |
+
|
| 71 |
extractor = PatientDataExtractor(patients_data, "json")
|
| 72 |
|
| 73 |
if not extractor.patients:
|
| 74 |
+
logger.error("No patients found in the parsed data")
|
| 75 |
return None, "No patients found in the data", None, None
|
| 76 |
|
| 77 |
+
logger.info(f"Found {len(extractor.patients)} patients in the data")
|
| 78 |
+
|
| 79 |
matching_patients = []
|
| 80 |
for i in range(len(extractor.patients)):
|
| 81 |
extractor.set_patient_by_index(i)
|
| 82 |
patient_data = extractor.get_patient_dict()
|
| 83 |
|
| 84 |
+
patient_id_from_data = patient_data.get('id', '').strip().lower()
|
| 85 |
+
first_name_from_data = patient_data.get('first_name', '').strip().lower()
|
| 86 |
+
last_name_from_data = patient_data.get('last_name', '').strip().lower()
|
| 87 |
+
|
| 88 |
+
patient_id_input = patient_id.strip().lower()
|
| 89 |
+
first_name_input = first_name.strip().lower()
|
| 90 |
+
last_name_input = last_name.strip().lower()
|
| 91 |
+
|
| 92 |
+
logger.debug(f"Comparing - ID: {patient_id_input} vs {patient_id_from_data}, "
|
| 93 |
+
f"First: {first_name_input} vs {first_name_from_data}, "
|
| 94 |
+
f"Last: {last_name_input} vs {last_name_from_data}")
|
| 95 |
|
| 96 |
+
matches = True
|
| 97 |
+
if patient_id_input and patient_id_from_data != patient_id_input:
|
| 98 |
+
matches = False
|
| 99 |
+
if first_name_input and first_name_from_data != first_name_input:
|
| 100 |
+
matches = False
|
| 101 |
+
if last_name_input and last_name_from_data != last_name_input:
|
| 102 |
+
matches = False
|
| 103 |
+
|
| 104 |
+
if matches:
|
| 105 |
matching_patients.append(patient_data)
|
| 106 |
+
logger.info(f"Found matching patient: {patient_data.get('id', 'unknown')}")
|
| 107 |
|
| 108 |
if not matching_patients:
|
| 109 |
+
search_criteria = f"ID: {patient_id or 'N/A'}, First: {first_name or 'N/A'}, Last: {last_name or 'N/A'}"
|
| 110 |
+
logger.warning(f"No patients matched criteria: {search_criteria}")
|
| 111 |
+
return None, f"No patients found matching criteria: {search_criteria}", None, None
|
| 112 |
|
| 113 |
patient_data = matching_patients[0]
|
| 114 |
+
logger.info(f"Selected patient data: {patient_data}")
|
| 115 |
|
|
|
|
| 116 |
basic_summary = format_discharge_summary(patient_data)
|
| 117 |
+
ai_summary = generate_ai_discharge_summary(patient_data, client)
|
| 118 |
|
| 119 |
if not ai_summary:
|
| 120 |
return None, "Failed to generate AI summary", basic_summary, None
|