Update app.py
Browse files
app.py
CHANGED
@@ -1,91 +1,127 @@
|
|
1 |
import streamlit as st
|
2 |
-
|
3 |
-
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
4 |
-
# 1) Initialize DB (imports models under the hood, then create_all)
|
5 |
-
from models.db import init_db
|
6 |
-
init_db()
|
7 |
-
|
8 |
-
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
9 |
-
# 2) First-run admin signup (before any queries to the user table)
|
10 |
-
from repositories.user_repo import UserRepo
|
11 |
from config.settings import settings
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
if st.button("Create Admin User"):
|
21 |
-
if new_user and new_name and new_pw:
|
22 |
-
repo.add_user(new_user, new_name, new_pw)
|
23 |
-
st.success(f"β
Admin `{new_user}` created! Refresh the page to log in.")
|
24 |
-
else:
|
25 |
-
st.error("All fields are required.")
|
26 |
-
st.stop()
|
27 |
|
28 |
-
#
|
29 |
-
#
|
30 |
-
|
31 |
-
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
# 4) Core services & repositories
|
35 |
-
from agent.gemini_agent import chat_with_gemini
|
36 |
-
from clinical_nlp.umls_bioportal import lookup_umls, lookup_bioportal
|
37 |
-
from quantum.optimizer import optimize_treatment
|
38 |
-
from repositories.chat_repo import ChatRepo
|
39 |
-
|
40 |
-
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
41 |
-
# 5) Logging & metrics
|
42 |
-
from services.logger import logger
|
43 |
-
from services.metrics import CHAT_COUNT, OPTIMIZE_COUNT
|
44 |
|
45 |
-
#
|
46 |
-
|
47 |
-
st.
|
48 |
-
st.
|
49 |
-
st.
|
|
|
|
|
50 |
|
51 |
-
tab1, tab2 = st.tabs(["π©Ί Consult", "π Reports"])
|
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 |
-
st.
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
-
|
90 |
-
st.markdown("---")
|
91 |
-
st.caption("Powered by Gemini LLM β’ UMLS/BioPortal β’ Quantum-inspired optimization")
|
|
|
1 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
from config.settings import settings
|
3 |
+
from models import create_db_and_tables, get_session_context, User, ChatMessage, ChatSession
|
4 |
+
from models.user import UserCreate # For type hinting
|
5 |
+
from services.auth import create_user_in_db, authenticate_user
|
6 |
+
from services.logger import app_logger
|
7 |
+
# Agent will be initialized and used in specific pages like Consult.py
|
8 |
+
# from agent import get_agent_executor # Import in pages where needed
|
9 |
|
10 |
+
# --- Page Configuration ---
|
11 |
+
st.set_page_config(
|
12 |
+
page_title=settings.APP_TITLE,
|
13 |
+
page_icon="βοΈ", # You can use an emoji or a path to an image
|
14 |
+
layout="wide",
|
15 |
+
initial_sidebar_state="expanded"
|
16 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
# --- Database Initialization ---
|
19 |
+
@st.cache_resource # Ensure this runs only once
|
20 |
+
def init_db():
|
21 |
+
app_logger.info("Initializing database and tables...")
|
22 |
+
create_db_and_tables()
|
23 |
+
app_logger.info("Database initialized.")
|
24 |
|
25 |
+
init_db()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
+
# --- Session State Initialization ---
|
28 |
+
if 'authenticated_user' not in st.session_state:
|
29 |
+
st.session_state.authenticated_user = None # Stores User object upon successful login
|
30 |
+
if 'current_chat_session_id' not in st.session_state:
|
31 |
+
st.session_state.current_chat_session_id = None
|
32 |
+
if 'chat_messages' not in st.session_state: # For the current active chat
|
33 |
+
st.session_state.chat_messages = []
|
34 |
|
|
|
35 |
|
36 |
+
# --- Authentication Logic ---
|
37 |
+
def display_login_form():
|
38 |
+
with st.form("login_form"):
|
39 |
+
st.subheader("Login")
|
40 |
+
username = st.text_input("Username")
|
41 |
+
password = st.text_input("Password", type="password")
|
42 |
+
submit_button = st.form_submit_button("Login")
|
43 |
|
44 |
+
if submit_button:
|
45 |
+
user = authenticate_user(username, password)
|
46 |
+
if user:
|
47 |
+
st.session_state.authenticated_user = user
|
48 |
+
st.success(f"Welcome back, {user.username}!")
|
49 |
+
# Create a new chat session for the user upon login
|
50 |
+
with get_session_context() as db_session:
|
51 |
+
new_chat_session = ChatSession(user_id=user.id, title=f"Session for {user.username}")
|
52 |
+
db_session.add(new_chat_session)
|
53 |
+
db_session.commit()
|
54 |
+
db_session.refresh(new_chat_session)
|
55 |
+
st.session_state.current_chat_session_id = new_chat_session.id
|
56 |
+
st.session_state.chat_messages = [] # Clear previous messages
|
57 |
+
st.rerun() # Rerun to reflect login state
|
58 |
+
else:
|
59 |
+
st.error("Invalid username or password.")
|
60 |
|
61 |
+
def display_signup_form():
|
62 |
+
with st.form("signup_form"):
|
63 |
+
st.subheader("Sign Up")
|
64 |
+
new_username = st.text_input("Choose a Username")
|
65 |
+
new_email = st.text_input("Email (Optional)")
|
66 |
+
new_password = st.text_input("Choose a Password", type="password")
|
67 |
+
confirm_password = st.text_input("Confirm Password", type="password")
|
68 |
+
submit_button = st.form_submit_button("Sign Up")
|
69 |
|
70 |
+
if submit_button:
|
71 |
+
if not new_username or not new_password:
|
72 |
+
st.error("Username and password are required.")
|
73 |
+
elif new_password != confirm_password:
|
74 |
+
st.error("Passwords do not match.")
|
75 |
+
else:
|
76 |
+
user_data = UserCreate(
|
77 |
+
username=new_username,
|
78 |
+
password=new_password,
|
79 |
+
email=new_email if new_email else None
|
80 |
+
)
|
81 |
+
user = create_user_in_db(user_data)
|
82 |
+
if user:
|
83 |
+
st.success(f"Account created for {user.username}. Please log in.")
|
84 |
+
# Optionally log them in directly:
|
85 |
+
# st.session_state.authenticated_user = user
|
86 |
+
# st.rerun()
|
87 |
+
else:
|
88 |
+
st.error("Username might already be taken or an error occurred.")
|
89 |
|
90 |
+
# --- Main App Logic ---
|
91 |
+
if not st.session_state.authenticated_user:
|
92 |
+
st.title(f"Welcome to {settings.APP_TITLE}")
|
93 |
+
st.markdown("Your AI-powered partner for advanced healthcare insights.")
|
94 |
+
|
95 |
+
login_tab, signup_tab = st.tabs(["Login", "Sign Up"])
|
96 |
+
with login_tab:
|
97 |
+
display_login_form()
|
98 |
+
with signup_tab:
|
99 |
+
display_signup_form()
|
100 |
+
else:
|
101 |
+
# If authenticated, Streamlit automatically navigates to pages in the `pages/` directory.
|
102 |
+
# The content of `app.py` typically acts as the "Home" page if no `1_Home.py` exists,
|
103 |
+
# or it can be used for global elements like a custom sidebar if not using Streamlit's default page navigation.
|
104 |
|
105 |
+
# Custom Sidebar for logged-in users (Streamlit handles page navigation automatically)
|
106 |
+
with st.sidebar:
|
107 |
+
st.markdown(f"### Welcome, {st.session_state.authenticated_user.username}!")
|
108 |
+
st.image("assets/logo.png", width=100) # Display logo if available
|
109 |
+
st.markdown("---")
|
110 |
+
|
111 |
+
if st.button("Logout"):
|
112 |
+
st.session_state.authenticated_user = None
|
113 |
+
st.session_state.current_chat_session_id = None
|
114 |
+
st.session_state.chat_messages = []
|
115 |
+
st.success("You have been logged out.")
|
116 |
+
st.rerun()
|
117 |
+
|
118 |
+
# This content will show if no other page is selected, or if you don't have a 1_Home.py
|
119 |
+
# If you have 1_Home.py, Streamlit will show that by default after login.
|
120 |
+
# So, this part might be redundant if 1_Home.py exists and is the intended landing.
|
121 |
+
st.sidebar.success("Select a page above to get started.")
|
122 |
+
st.markdown(f"# {settings.APP_TITLE}")
|
123 |
+
st.markdown("Navigate using the sidebar to consult with the AI or view your reports.")
|
124 |
+
st.markdown("---")
|
125 |
+
st.info("This is the main application area. If you see this, ensure you have a `pages/1_Home.py` or that this `app.py` is your intended landing page after login.")
|
126 |
|
127 |
+
app_logger.info("Streamlit app initialized and running.")
|
|
|
|