gladguy commited on
Commit
aed25cb
Β·
1 Parent(s): 5625e63

Add student database with medical school field and password-protected admin panel

Browse files
Files changed (1) hide show
  1. app.py +191 -22
app.py CHANGED
@@ -7,6 +7,8 @@ from PIL import Image
7
  import PyPDF2
8
  from pdf2image import convert_from_path
9
  import tempfile
 
 
10
 
11
  # Load environment variables
12
  load_dotenv()
@@ -15,6 +17,60 @@ SERPAPI_KEY = os.getenv("SERPAPI_KEY")
15
  HYPERBOLIC_API_KEY = os.getenv("HYPERBOLIC_API_KEY")
16
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  # Hyperbolic API configuration
19
  HYPERBOLIC_API_URL = "https://api.hyperbolic.xyz/v1/chat/completions"
20
  HYPERBOLIC_MODEL = "meta-llama/Llama-3.3-70B-Instruct"
@@ -665,7 +721,7 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
665
  )
666
  gr.Markdown("---")
667
  gr.Markdown("## πŸ‘¨β€βš•οΈ Let's Get Started!")
668
- gr.Markdown("Please enter your name to begin your personalized learning journey.")
669
 
670
  with gr.Row():
671
  with gr.Column(scale=1):
@@ -677,6 +733,12 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
677
  lines=1,
678
  scale=1
679
  )
 
 
 
 
 
 
680
  welcome_submit_btn = gr.Button(
681
  "πŸš€ Start Learning",
682
  variant="primary",
@@ -697,23 +759,24 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
697
 
698
  # Display student name
699
  student_name_display = gr.Markdown("")
700
-
701
- with gr.Tabs(visible=False) as tabs:
702
- # LEARNING MODE TAB
703
- with gr.Tab("πŸ“š Learning Mode"):
704
- # Search and examples at the top
705
- with gr.Row():
706
- query_input = gr.Textbox(
707
- label="Ask an Anatomy Question",
708
- placeholder="e.g., Show me the Circle of Willis",
709
- lines=2
710
- )
711
-
712
- # Examples
713
- gr.Examples(
714
- examples=[
715
- ["Show me the Circle of Willis"],
716
- ["Brachial plexus anatomy"],
 
717
  ["Carpal bones arrangement"],
718
  ["Layers of the scalp"],
719
  ["Anatomy of the heart chambers"],
@@ -867,15 +930,55 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
867
  outputs=[current_question_idx]
868
  )
869
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
870
 
871
 
872
  # Welcome Screen Handler
873
- def handle_welcome_submit(name):
874
  """Handle welcome screen submission."""
875
  if not name or not name.strip():
876
  return gr.update(), gr.update(), gr.update(), gr.update(), "" # Don't proceed if name is empty
877
 
878
- greeting = f"**Welcome, Doctor {name}!** πŸ‘‹"
 
 
 
 
 
 
879
  return (
880
  gr.update(visible=False), # Hide welcome screen
881
  gr.update(visible=True), # Show main app
@@ -886,14 +989,20 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
886
 
887
  welcome_submit_btn.click(
888
  fn=handle_welcome_submit,
889
- inputs=[welcome_name_input],
890
  outputs=[welcome_screen, main_app, tabs, student_name_display, student_name_state]
891
  )
892
 
893
  # Also allow Enter key to submit
894
  welcome_name_input.submit(
895
  fn=handle_welcome_submit,
896
- inputs=[welcome_name_input],
 
 
 
 
 
 
897
  outputs=[welcome_screen, main_app, tabs, student_name_display, student_name_state]
898
  )
899
 
@@ -953,6 +1062,66 @@ with gr.Blocks(title="AnatomyBot - MBBS Anatomy Tutor") as demo:
953
  question_audio # Output audio for next question
954
  ]
955
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
956
 
957
  if __name__ == "__main__":
958
  # Check if API keys are configured
 
7
  import PyPDF2
8
  from pdf2image import convert_from_path
9
  import tempfile
10
+ import sqlite3
11
+ from datetime import datetime
12
 
13
  # Load environment variables
14
  load_dotenv()
 
17
  HYPERBOLIC_API_KEY = os.getenv("HYPERBOLIC_API_KEY")
18
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
19
 
20
+ # Admin password
21
+ ADMIN_PASSWORD = "BT54iv!@"
22
+
23
+ # Database setup
24
+ DB_PATH = "students.db"
25
+
26
+ def init_database():
27
+ """Initialize the SQLite database and create students table if it doesn't exist."""
28
+ conn = sqlite3.connect(DB_PATH)
29
+ cursor = conn.cursor()
30
+ cursor.execute("""
31
+ CREATE TABLE IF NOT EXISTS students (
32
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ name TEXT NOT NULL,
34
+ medical_school TEXT NOT NULL,
35
+ registration_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
36
+ )
37
+ """)
38
+ conn.commit()
39
+ conn.close()
40
+
41
+ def save_student(name, medical_school):
42
+ """Save student information to the database."""
43
+ try:
44
+ conn = sqlite3.connect(DB_PATH)
45
+ cursor = conn.cursor()
46
+ cursor.execute(
47
+ "INSERT INTO students (name, medical_school) VALUES (?, ?)",
48
+ (name, medical_school)
49
+ )
50
+ conn.commit()
51
+ conn.close()
52
+ return True
53
+ except Exception as e:
54
+ print(f"Error saving student: {e}")
55
+ return False
56
+
57
+ def get_all_students():
58
+ """Retrieve all students from the database."""
59
+ try:
60
+ conn = sqlite3.connect(DB_PATH)
61
+ cursor = conn.cursor()
62
+ cursor.execute("SELECT id, name, medical_school, registration_date FROM students ORDER BY registration_date DESC")
63
+ students = cursor.fetchall()
64
+ conn.close()
65
+ return students
66
+ except Exception as e:
67
+ print(f"Error retrieving students: {e}")
68
+ return []
69
+
70
+ # Initialize database on startup
71
+ init_database()
72
+
73
+
74
  # Hyperbolic API configuration
75
  HYPERBOLIC_API_URL = "https://api.hyperbolic.xyz/v1/chat/completions"
76
  HYPERBOLIC_MODEL = "meta-llama/Llama-3.3-70B-Instruct"
 
721
  )
722
  gr.Markdown("---")
723
  gr.Markdown("## πŸ‘¨β€βš•οΈ Let's Get Started!")
724
+ gr.Markdown("Please enter your information to begin your personalized learning journey.")
725
 
726
  with gr.Row():
727
  with gr.Column(scale=1):
 
733
  lines=1,
734
  scale=1
735
  )
736
+ welcome_school_input = gr.Textbox(
737
+ label="Medical School",
738
+ placeholder="Enter your medical school (e.g., King Saud University)",
739
+ lines=1,
740
+ scale=1
741
+ )
742
  welcome_submit_btn = gr.Button(
743
  "πŸš€ Start Learning",
744
  variant="primary",
 
759
 
760
  # Display student name
761
  student_name_display = gr.Markdown("")
762
+
763
+ # Tabs are inside main_app so they're hidden initially
764
+ with gr.Tabs() as tabs:
765
+ # LEARNING MODE TAB
766
+ with gr.Tab("πŸ“š Learning Mode"):
767
+ # Search and examples at the top
768
+ with gr.Row():
769
+ query_input = gr.Textbox(
770
+ label="Ask an Anatomy Question",
771
+ placeholder="e.g., Show me the Circle of Willis",
772
+ lines=2
773
+ )
774
+
775
+ # Examples
776
+ gr.Examples(
777
+ examples=[
778
+ ["Show me the Circle of Willis"],
779
+ ["Brachial plexus anatomy"],
780
  ["Carpal bones arrangement"],
781
  ["Layers of the scalp"],
782
  ["Anatomy of the heart chambers"],
 
930
  outputs=[current_question_idx]
931
  )
932
 
933
+ # ADMIN PANEL TAB
934
+ with gr.Tab("πŸ” Admin Panel") as admin_tab:
935
+ gr.Markdown("## Admin Panel - Student Database")
936
+ gr.Markdown("Enter the admin password to view registered students.")
937
+
938
+ # Password input
939
+ with gr.Row():
940
+ admin_password_input = gr.Textbox(
941
+ label="Admin Password",
942
+ placeholder="Enter admin password",
943
+ type="password",
944
+ scale=2
945
+ )
946
+ admin_login_btn = gr.Button("πŸ”“ Login", variant="primary", scale=1)
947
+
948
+ admin_status = gr.Markdown("")
949
+
950
+ # Admin content (hidden until authenticated)
951
+ with gr.Column(visible=False) as admin_content:
952
+ gr.Markdown("### πŸ“Š Registered Students")
953
+
954
+ admin_stats = gr.Markdown("")
955
+
956
+ with gr.Row():
957
+ refresh_btn = gr.Button("πŸ”„ Refresh Data", variant="secondary")
958
+ logout_btn = gr.Button("πŸšͺ Logout", variant="secondary")
959
+
960
+ students_table = gr.Dataframe(
961
+ headers=["ID", "Name", "Medical School", "Registration Date"],
962
+ label="Students Database",
963
+ interactive=False,
964
+ wrap=True
965
+ )
966
+
967
 
968
 
969
  # Welcome Screen Handler
970
+ def handle_welcome_submit(name, medical_school):
971
  """Handle welcome screen submission."""
972
  if not name or not name.strip():
973
  return gr.update(), gr.update(), gr.update(), gr.update(), "" # Don't proceed if name is empty
974
 
975
+ if not medical_school or not medical_school.strip():
976
+ return gr.update(), gr.update(), gr.update(), gr.update(), "" # Don't proceed if medical school is empty
977
+
978
+ # Save to database
979
+ save_student(name.strip(), medical_school.strip())
980
+
981
+ greeting = f"**Welcome, Doctor {name}!** πŸ‘‹ from {medical_school}"
982
  return (
983
  gr.update(visible=False), # Hide welcome screen
984
  gr.update(visible=True), # Show main app
 
989
 
990
  welcome_submit_btn.click(
991
  fn=handle_welcome_submit,
992
+ inputs=[welcome_name_input, welcome_school_input],
993
  outputs=[welcome_screen, main_app, tabs, student_name_display, student_name_state]
994
  )
995
 
996
  # Also allow Enter key to submit
997
  welcome_name_input.submit(
998
  fn=handle_welcome_submit,
999
+ inputs=[welcome_name_input, welcome_school_input],
1000
+ outputs=[welcome_screen, main_app, tabs, student_name_display, student_name_state]
1001
+ )
1002
+
1003
+ welcome_school_input.submit(
1004
+ fn=handle_welcome_submit,
1005
+ inputs=[welcome_name_input, welcome_school_input],
1006
  outputs=[welcome_screen, main_app, tabs, student_name_display, student_name_state]
1007
  )
1008
 
 
1062
  question_audio # Output audio for next question
1063
  ]
1064
  )
1065
+
1066
+ # Admin Panel Handlers
1067
+ def admin_login(password):
1068
+ """Verify admin password and show admin content."""
1069
+ if password == ADMIN_PASSWORD:
1070
+ students = get_all_students()
1071
+ total_students = len(students)
1072
+ stats = f"**Total Registered Students:** {total_students}"
1073
+ return (
1074
+ gr.update(value="βœ… Login successful!", visible=True),
1075
+ gr.update(visible=True), # Show admin content
1076
+ stats,
1077
+ students
1078
+ )
1079
+ else:
1080
+ return (
1081
+ gr.update(value="❌ Invalid password. Access denied.", visible=True),
1082
+ gr.update(visible=False), # Hide admin content
1083
+ "",
1084
+ []
1085
+ )
1086
+
1087
+ def admin_logout():
1088
+ """Logout from admin panel."""
1089
+ return (
1090
+ gr.update(value=""), # Clear password
1091
+ gr.update(value=""), # Clear status
1092
+ gr.update(visible=False), # Hide admin content
1093
+ "", # Clear stats
1094
+ [] # Clear table
1095
+ )
1096
+
1097
+ def refresh_students():
1098
+ """Refresh the students table."""
1099
+ students = get_all_students()
1100
+ total_students = len(students)
1101
+ stats = f"**Total Registered Students:** {total_students}"
1102
+ return stats, students
1103
+
1104
+ admin_login_btn.click(
1105
+ fn=admin_login,
1106
+ inputs=[admin_password_input],
1107
+ outputs=[admin_status, admin_content, admin_stats, students_table]
1108
+ )
1109
+
1110
+ admin_password_input.submit(
1111
+ fn=admin_login,
1112
+ inputs=[admin_password_input],
1113
+ outputs=[admin_status, admin_content, admin_stats, students_table]
1114
+ )
1115
+
1116
+ logout_btn.click(
1117
+ fn=admin_logout,
1118
+ outputs=[admin_password_input, admin_status, admin_content, admin_stats, students_table]
1119
+ )
1120
+
1121
+ refresh_btn.click(
1122
+ fn=refresh_students,
1123
+ outputs=[admin_stats, students_table]
1124
+ )
1125
 
1126
  if __name__ == "__main__":
1127
  # Check if API keys are configured