File size: 8,690 Bytes
310dade 6145bc0 79d193c 310dade e9c724f 864b488 310dade 79d193c 0b77233 310dade 864b488 310dade 0b77233 e9c724f 0b77233 864b488 310dade 79d193c 0b77233 310dade 0b77233 0a2437f 310dade 79d193c 0b77233 c21fd02 0b77233 0a2437f 310dade 0b77233 e9c724f 0b77233 64f8a92 0b77233 79d193c e9c724f 79d193c 310dade 79d193c e9c724f 04ae885 310dade e9c724f 04ae885 79d193c 04ae885 79d193c 310dade 79d193c e9c724f 310dade 04ae885 310dade 04ae885 79d193c c21fd02 310dade c21fd02 04ae885 79d193c 0b77233 e9c724f 64f8a92 310dade 0b77233 e9c724f 0b77233 64f8a92 0b77233 310dade 0b77233 310dade 0b77233 310dade 04ae885 0b77233 c21fd02 e9c724f 0a2437f 310dade 0b77233 310dade e9c724f 310dade e9c724f 310dade c21fd02 310dade 79d193c 0b77233 04ae885 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# /home/user/app/app.py
import streamlit as st
from pathlib import Path
from sqlmodel import select # <--- IMPORT SELECT FOR SQLMODEL QUERIES
from config.settings import settings
from models import (
create_db_and_tables,
get_session_context, # Your SQLModel session context manager
User,
ChatMessage,
ChatSession
)
from models.user import UserCreate
from services.auth import create_user_in_db, authenticate_user
from services.logger import app_logger
from assets.logo import get_logo_path
# --- Page Configuration --- (Assuming this is already correct)
st.set_page_config(
page_title=settings.APP_TITLE,
page_icon="⚕️",
layout="wide",
initial_sidebar_state="expanded"
)
# --- Database Initialization --- (Assuming this is already correct)
@st.cache_resource
def init_db():
app_logger.info("Initializing database and tables...")
create_db_and_tables() # This uses SQLModel.metadata.create_all(engine)
app_logger.info("Database initialized.")
init_db()
# --- Session State Initialization --- (Assuming this is already correct)
if 'authenticated_user_id' not in st.session_state:
st.session_state.authenticated_user_id = None
if 'authenticated_username' not in st.session_state:
st.session_state.authenticated_username = None
if 'current_chat_session_id' not in st.session_state:
st.session_state.current_chat_session_id = None
if 'chat_messages' not in st.session_state:
st.session_state.chat_messages = []
# --- Authentication Logic ---
def display_login_form():
with st.form("login_form"):
st.subheader("Login")
username_input = st.text_input("Username", key="login_username_input")
password_input = st.text_input("Password", type="password", key="login_password_input")
submit_button = st.form_submit_button("Login")
if submit_button:
user_object_from_auth = authenticate_user(username_input, password_input)
if user_object_from_auth:
st.success(f"Welcome back, {username_input}!")
app_logger.info(f"User {username_input} authenticated successfully.")
try:
with get_session_context() as db_session: # db_session is a SQLModel Session
# --- SQLMODEL QUERY ---
statement = select(User).where(User.username == username_input)
live_user = db_session.exec(statement).first()
# --------------------
if not live_user:
st.error("Authentication inconsistency. User details not found after login. Please contact support.")
app_logger.error(f"CRITICAL: User '{username_input}' authenticated but then not found in DB by username.")
st.session_state.authenticated_user_id = None
st.session_state.authenticated_username = None
st.rerun()
return
st.session_state.authenticated_user_id = live_user.id
st.session_state.authenticated_username = live_user.username
app_logger.info(f"Stored user ID {live_user.id} and username '{live_user.username}' in session state.")
new_chat_session = ChatSession(user_id=live_user.id, title=f"Session for {live_user.username} ({Path(settings.APP_TITLE).name})")
db_session.add(new_chat_session)
# db_session.commit() # Handled by get_session_context manager
db_session.refresh(new_chat_session) # Refresh after add, before commit if ID needed
st.session_state.current_chat_session_id = new_chat_session.id
st.session_state.chat_messages = []
app_logger.info(f"New chat session (ID: {new_chat_session.id}) created for user {live_user.username}.")
# Session commit and close handled by get_session_context
st.rerun()
except Exception as e:
app_logger.error(f"Error during post-login session setup for user {username_input}: {e}", exc_info=True)
st.error(f"Could not complete login process: {e}")
st.session_state.authenticated_user_id = None
st.session_state.authenticated_username = None
else:
st.error("Invalid username or password.")
app_logger.warning(f"Failed login attempt for username: {username_input}")
# display_signup_form() remains largely the same as it calls create_user_in_db,
# which should internally use SQLModel syntax if it interacts with the DB.
# --- Main App Logic --- (Remains the same, using updated session state keys)
# ... (rest of app.py as previously provided, ensuring it uses authenticated_user_id and authenticated_username)
# For brevity, I'm omitting the parts of app.py that don't change due to SQLModel query syntax.
# The signup form and the main structure checking st.session_state.get("authenticated_user_id")
# and the sidebar display are correct from the previous version.
# Ensure any other direct DB queries in app.py (if any were added) are also updated.
# (Make sure the rest of your app.py from the previous good version is here)
def display_signup_form():
with st.form("signup_form"):
st.subheader("Sign Up")
new_username = st.text_input("Choose a Username", key="signup_username_input")
new_email = st.text_input("Email (Optional)", key="signup_email_input")
new_password = st.text_input("Choose a Password", type="password", key="signup_password_input")
confirm_password = st.text_input("Confirm Password", type="password", key="signup_confirm_password_input")
submit_button = st.form_submit_button("Sign Up")
if submit_button:
if not new_username or not new_password:
st.error("Username and password are required.")
elif len(new_password) < 6:
st.error("Password must be at least 6 characters long.")
elif new_password != confirm_password:
st.error("Passwords do not match.")
else:
user_data = UserCreate(
username=new_username,
password=new_password,
email=new_email if new_email else None
)
user = create_user_in_db(user_data)
if user:
st.success(f"Account created for {new_username}. Please log in.")
app_logger.info(f"Account created for {new_username}.")
else:
st.error("Username might already be taken or another error occurred during signup.")
app_logger.warning(f"Signup failed for username: {new_username}")
if not st.session_state.get("authenticated_user_id"):
st.title(f"Welcome to {settings.APP_TITLE}")
st.markdown("Your AI-powered partner for advanced healthcare insights.")
login_tab, signup_tab = st.tabs(["Login", "Sign Up"])
with login_tab:
display_login_form()
with signup_tab:
display_signup_form()
else:
with st.sidebar:
logo_path_str_sidebar = get_logo_path()
if logo_path_str_sidebar:
logo_file_sidebar = Path(logo_path_str_sidebar)
if logo_file_sidebar.exists():
try:
st.image(str(logo_file_sidebar), width=100)
except Exception as e:
app_logger.warning(f"Could not display logo in sidebar from path '{logo_path_str_sidebar}': {e}")
elif settings.APP_TITLE:
st.sidebar.markdown(f"#### {settings.APP_TITLE}")
username_for_display = st.session_state.get("authenticated_username", "User")
st.sidebar.markdown(f"### Welcome, {username_for_display}!")
st.sidebar.markdown("---")
if st.sidebar.button("Logout", key="sidebar_logout_button"):
logged_out_username = st.session_state.get("authenticated_username", "UnknownUser")
app_logger.info(f"User {logged_out_username} logging out.")
st.session_state.authenticated_user_id = None
st.session_state.authenticated_username = None
st.session_state.current_chat_session_id = None
st.session_state.chat_messages = []
st.success("You have been logged out.")
st.rerun()
app_logger.info(f"Streamlit app '{settings.APP_TITLE}' initialized and running.") |