mgbam commited on
Commit
0b77233
Β·
verified Β·
1 Parent(s): 9b49791

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -77
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
- repo = UserRepo(settings.database_url)
14
- if not repo.get_all_users():
15
- st.title("πŸš€ Welcome to Quantum Healthcare AI")
16
- st.warning("No users exist yet. Create the first admin account below:")
17
- new_user = st.text_input("Username")
18
- new_name = st.text_input("Full name")
19
- new_pw = st.text_input("Password", type="password")
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
- # 3) Authentication
30
- from services.auth import authenticator, require_login
31
- username = require_login()
 
 
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
- # 6) UI Layout
47
- st.set_page_config(page_title="Quantum Healthcare AI", layout="wide")
48
- st.image("assets/logo.png", width=64)
49
- st.title(f"Hello, {username}!")
 
 
50
 
51
- tab1, tab2 = st.tabs(["🩺 Consult", "πŸ“Š Reports"])
52
 
53
- with tab1:
54
- query = st.text_area("Describe your symptoms or ask a clinical question:", height=100)
 
 
 
 
 
55
 
56
- if st.button("Ask Gemini"):
57
- CHAT_COUNT.inc()
58
- with st.spinner("πŸ€– Consulting Gemini..."):
59
- response = chat_with_gemini(username, query)
60
- logger.info(f"[Chat] user={username} prompt={query!r}")
61
- st.markdown(f"**AI Response:** {response}")
62
- ChatRepo().save(user=username, prompt=query, response=response)
 
 
 
 
 
 
 
 
 
63
 
64
- with st.expander("πŸ”Ž UMLS Concept Lookup"):
65
- umls_results = lookup_umls(query)
66
- st.write(umls_results or "No concepts found in UMLS.")
 
 
 
 
 
67
 
68
- with st.expander("πŸ”¬ BioPortal Concept Lookup"):
69
- bio_results = lookup_bioportal(query)
70
- st.write(bio_results or "No matches found in BioPortal.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- if st.button("🧬 Quantum Optimize Care Plan"):
73
- OPTIMIZE_COUNT.inc()
74
- with st.spinner("βš›οΈ Running quantum-inspired optimizer..."):
75
- plan = optimize_treatment(query)
76
- logger.info(f"[Optimize] user={username} plan={plan}")
77
- st.markdown("### Optimized Treatment Plan")
78
- st.json(plan)
 
 
 
 
 
 
 
79
 
80
- with tab2:
81
- st.header("Generate PDF Report of Recent Chats")
82
- if st.button("Download Last 5 Chats"):
83
- recent = ChatRepo().get_recent(user=username, limit=5)
84
- from services.pdf_report import generate_pdf
85
- pdf_path = generate_pdf({"Recent Chats": recent})
86
- with open(pdf_path, "rb") as f:
87
- st.download_button("Download PDF", f, file_name=pdf_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
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.")