GRADEVIEW / app.py
MENG21's picture
8e2b0d5
raw
history blame
6.94 kB
import streamlit as st
import pandas as pd
import numpy as np
from cryptography.fernet import Fernet
import os
import io
from dotenv import load_dotenv
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import Flow
from google.auth.transport.requests import Request
import json
# Load environment variables from .env file
load_dotenv()
# Set page configuration
st.set_page_config(page_title="Student Grade Lookup", page_icon="πŸ“š", layout="centered")
# Custom CSS to improve the app's appearance
st.markdown("""
<style>
.reportview-container {
background: #f0f2f6
}
.big-font {
font-size:20px !important;
font-weight: bold;
}
.stAlert > div {
padding-top: 15px;
padding-bottom: 15px;
}
.message {
font-size: 18px;
font-style: italic;
margin-top: 20px;
}
.warning-message {
font-size: 18px;
font-weight: bold;
color: #ff9800;
margin-top: 20px;
}
</style>
""", unsafe_allow_html=True)
# Google OAuth configuration
CLIENT_CONFIG = {
"web": {
"client_id": os.getenv("GOOGLE_CLIENT_ID"),
"client_secret": os.getenv("GOOGLE_CLIENT_SECRET"),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
}
}
SCOPES = ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', 'openid']
# Function to create OAuth flow
def create_flow():
flow = Flow.from_client_config(
client_config=CLIENT_CONFIG,
scopes=SCOPES,
redirect_uri="https://meng21-gradeview.hf.space/" # Update this with your Streamlit app's URL
)
return flow
# Function to check if the user is logged in
def is_logged_in():
return 'credentials' in st.session_state
# Load and decrypt the CSV file
@st.cache_data
def load_data():
encryption_key = os.getenv('ENCRYPTION_KEY')
if not encryption_key:
st.error("Encryption key not found in environment variables.")
return pd.DataFrame()
f = Fernet(encryption_key.encode())
try:
with open('encrypted_grades.csv', 'rb') as file:
encrypted_data = file.read()
decrypted_data = f.decrypt(encrypted_data)
return pd.read_csv(io.StringIO(decrypted_data.decode()))
except Exception as e:
st.error(f"Error decrypting file: {str(e)}")
return pd.DataFrame()
# Main function to run the Streamlit app
def main():
if not is_logged_in():
st.title('πŸ“š Student Grade Lookup')
st.markdown("---")
st.write("Please log in with your CSPC Google account to access the grade lookup.")
if st.button("Login with Google"):
flow = create_flow()
authorization_url, _ = flow.authorization_url(prompt="consent")
st.markdown(f"[Login with Google]({authorization_url})")
else:
st.title('πŸ“š Student Grade Lookup')
st.markdown("---")
# Load the data
df = load_data()
# Create two columns
col1, col2 = st.columns([2, 1])
with col1:
# Create an input field for the student ID
student_id = st.text_input('Enter Student ID:', placeholder="e.g., C21101100")
with col2:
st.write("")
st.write("")
search_button = st.button('Search', use_container_width=True)
if student_id and search_button:
# Search for the student in the dataframe
student = df[df['ID'].astype(str) == student_id]
if not student.empty:
st.markdown("---")
st.subheader('Student Information:')
# Display student information in a more structured way
col1, col2 = st.columns(2)
with col1:
st.markdown("<p class='big-font'>Name</p>", unsafe_allow_html=True)
st.write(f"{student['NAME'].values[0]}")
st.markdown("<p class='big-font'>ID</p>", unsafe_allow_html=True)
st.write(f"{student_id}")
with col2:
st.markdown("<p class='big-font'>Grade</p>", unsafe_allow_html=True)
# Check if grade is NA
grade = student['GRADE'].values[0]
if pd.isna(grade):
grade_display = "N/A"
else:
grade_display = f"{grade:.2f}"
st.write(grade_display)
st.markdown("<p class='big-font'>Remarks</p>", unsafe_allow_html=True)
remarks = student['REMARKS'].values[0]
if remarks == "Passed":
st.success(remarks)
elif remarks == "Conditional":
st.warning(remarks)
else:
st.write(remarks)
# Add personalized message based on grade
if not pd.isna(grade):
if grade > 1.9:
message = f"Keep up the good work! Your grade of {grade:.2f} shows dedication. Consider seeking additional support to further improve your performance."
st.markdown(f"<p class='message'>{message}</p>", unsafe_allow_html=True)
else:
message = f"Congratulations! Your outstanding grade of {grade:.2f} demonstrates exceptional performance. Keep up the excellent work!"
st.markdown(f"<p class='message'>{message}</p>", unsafe_allow_html=True)
# Add warning message for Conditional remarks
if remarks == "Conditional":
warning_message = "Warning: Your current status is Conditional. You need to pass or achieve a higher grade in the final term to improve your standing."
st.markdown(f"<p class='warning-message'>{warning_message}</p>", unsafe_allow_html=True)
else:
st.error('Student ID not found. Please try again.')
if st.button("Logout"):
del st.session_state['credentials']
st.rerun()
# Function to handle OAuth callback
def handle_callback():
flow = create_flow()
flow.fetch_token(code=st.query_params["code"])
credentials = flow.credentials
st.session_state['credentials'] = credentials.to_json()
return credentials
if __name__ == '__main__':
if 'code' in st.query_params:
handle_callback()
st.rerun()
main()