|
|
|
import streamlit as st |
|
from datetime import datetime |
|
from typing import List, Dict, Any |
|
from sqlmodel import select |
|
|
|
from config.settings import settings |
|
from models import ChatMessage, ChatSession |
|
from models.db import get_session_context |
|
from services.pdf_report import generate_pdf_report |
|
from services.logger import app_logger |
|
from services.metrics import log_report_generated |
|
|
|
|
|
if not st.session_state.get("authenticated_user_id"): |
|
st.warning("Please log in to access reports.") |
|
try: st.switch_page("app.py") |
|
except st.errors.StreamlitAPIException: st.info("Please navigate to the main login page manually.") |
|
st.stop() |
|
|
|
authenticated_user_id = st.session_state.get("authenticated_user_id") |
|
authenticated_username = st.session_state.get("authenticated_username", "User") |
|
app_logger.info(f"User '{authenticated_username}' (ID: {authenticated_user_id}) accessed Reports page.") |
|
|
|
st.title("Consultation Reports") |
|
st.markdown("View and download your past consultation sessions.") |
|
st.info(settings.MAIN_DISCLAIMER_SHORT) |
|
|
|
|
|
def get_user_chat_session_display_data(user_id: int) -> List[Dict[str, Any]]: |
|
app_logger.debug(f"Fetching session display data for user_id: {user_id}") |
|
session_data_list: List[Dict[str, Any]] = [] |
|
try: |
|
with get_session_context() as db: |
|
stmt = select(ChatSession.id, ChatSession.title, ChatSession.start_time, ChatSession.patient_context_summary)\ |
|
.where(ChatSession.user_id == user_id).order_by(ChatSession.start_time.desc()) |
|
results = db.exec(stmt).all() |
|
for row in results: |
|
session_data_list.append({ |
|
"id": row.id, "title": row.title, "start_time": row.start_time, |
|
"patient_context_summary": row.patient_context_summary |
|
}) |
|
app_logger.debug(f"Found {len(session_data_list)} session display entries for user {user_id}") |
|
except Exception as e: |
|
app_logger.error(f"Error fetching session display data for user {user_id}: {e}", exc_info=True) |
|
st.error("Could not load your chat sessions.") |
|
return session_data_list |
|
|
|
chat_session_display_items = get_user_chat_session_display_data(authenticated_user_id) |
|
|
|
if not chat_session_display_items: |
|
st.info("You have no past consultation sessions recorded.") |
|
st.stop() |
|
|
|
session_options = [] |
|
for s_data in chat_session_display_items: |
|
start_time_obj = s_data["start_time"] |
|
start_time_display = start_time_obj.strftime('%Y-%m-%d %H:%M') if start_time_obj else "N/A" |
|
title_display = s_data["title"] if s_data["title"] else f"Consult on {start_time_display}" |
|
display_string = f"ID: {s_data['id']} | Started: {start_time_display} | Title: {title_display}" |
|
session_options.append((display_string, s_data['id'])) |
|
|
|
selected_option_tuple = st.selectbox( |
|
"Select a Consultation Session:", options=session_options, format_func=lambda x: x[0], index=0 |
|
) |
|
|
|
if selected_option_tuple: |
|
selected_session_id = selected_option_tuple[1] |
|
MESSAGES_KEY = f"report_messages_for_session_{selected_session_id}" |
|
|
|
if MESSAGES_KEY not in st.session_state: |
|
app_logger.info(f"Fetching messages for report, session ID: {selected_session_id}") |
|
msg_data_list: List[Dict[str, Any]] = [] |
|
try: |
|
with get_session_context() as db: |
|
stmt = select(ChatMessage.role, ChatMessage.content, ChatMessage.timestamp, ChatMessage.tool_name)\ |
|
.where(ChatMessage.session_id == selected_session_id).order_by(ChatMessage.timestamp) |
|
results = db.exec(stmt).all() |
|
for row in results: |
|
msg_data_list.append({ |
|
"role": row.role, "content": row.content, "timestamp": row.timestamp, |
|
"tool_name": getattr(row, 'tool_name', None) |
|
}) |
|
st.session_state[MESSAGES_KEY] = msg_data_list |
|
except Exception as e: |
|
app_logger.error(f"Error fetching messages for report (session {selected_session_id}): {e}", exc_info=True) |
|
st.error("Could not load messages for this report.") |
|
st.session_state[MESSAGES_KEY] = [] |
|
else: |
|
app_logger.debug(f"Using cached messages from session_state for report, session ID: {selected_session_id}") |
|
msg_data_list = st.session_state[MESSAGES_KEY] |
|
|
|
selected_session_data = next((s for s in chat_session_display_items if s['id'] == selected_session_id), None) |
|
|
|
if selected_session_data: |
|
st.markdown("---") |
|
st.subheader(f"Report Preview for Session ID: {selected_session_data['id']}") |
|
start_t = selected_session_data["start_time"] |
|
st.write(f"**Started:** {start_t.strftime('%Y-%m-%d %H:%M:%S UTC') if start_t else 'N/A'}") |
|
st.write(f"**Title:** {selected_session_data['title'] or 'Untitled Session'}") |
|
if selected_session_data.get("patient_context_summary"): |
|
with st.expander("View Patient Context Provided", expanded=False): |
|
st.markdown(selected_session_data["patient_context_summary"]) |
|
|
|
if msg_data_list: |
|
with st.expander("View Chat Transcript", expanded=False): |
|
for idx, msg_d in enumerate(msg_data_list): |
|
if msg_d["role"] == "system": continue |
|
icon = "π§ββοΈ" if msg_d["role"] == "assistant" else "π€" |
|
if msg_d["role"] == "tool": icon = "π οΈ" |
|
ts_display = msg_d["timestamp"].strftime('%Y-%m-%d %H:%M:%S') if msg_d["timestamp"] else "N/A" |
|
st.markdown(f"**{icon} {msg_d['role'].capitalize()}** ({ts_display})") |
|
st.markdown(f"> ```\n{msg_d['content']}\n```") |
|
if idx < len(msg_data_list) - 1: st.markdown("---") |
|
|
|
st.markdown("---") |
|
try: |
|
|
|
|
|
|
|
pdf_report_messages = [ |
|
ChatMessage(**msg_d) for msg_d in msg_data_list |
|
] |
|
report_data_for_pdf = { |
|
"patient_name": authenticated_username, |
|
"session_id": selected_session_data['id'], |
|
"session_title": selected_session_data['title'] or 'Untitled Session', |
|
"session_start_time": selected_session_data['start_time'], |
|
"patient_context_summary": selected_session_data.get('patient_context_summary', "Not provided."), |
|
"messages": pdf_report_messages |
|
} |
|
|
|
pdf_bytes = generate_pdf_report(report_data_for_pdf) |
|
|
|
file_ts = datetime.now().strftime('%Y%m%d_%H%M%S') |
|
pdf_fn = f"Consult_Report_S{selected_session_id}_{file_ts}.pdf" |
|
st.download_button( |
|
label="Download Report as PDF", data=pdf_bytes, file_name=pdf_fn, mime="application/pdf", |
|
key=f"dl_pdf_s{selected_session_id}", on_click=log_report_generated, |
|
args=(authenticated_user_id, selected_session_id), help="Download consultation summary." |
|
) |
|
except Exception as e: |
|
app_logger.error(f"Error generating PDF for session {selected_session_id}: {e}", exc_info=True) |
|
st.error(f"Could not generate PDF report. Error: {type(e).__name__}") |
|
else: st.info("This session has no messages for the report.") |
|
else: st.error("Selected session data not found.") |
|
else: st.info("Select a session to view details.") |