clearance_stream / src /streamlit_app.py
Testys's picture
Update src/streamlit_app.py
d1ae182 verified
import streamlit as st
import requests
import json
# Backend URL
BASE_URL = "https://testys-clearance-sys.hf.space"
# Session state for auth
if 'token' not in st.session_state:
st.session_state.token = None
if 'user' not in st.session_state:
st.session_state.user = None
def login(username, password):
response = requests.post(f"{BASE_URL}/token", data={"username": username, "password": password})
if response.status_code == 200:
data = response.json()
st.session_state.token = data['access_token']
st.session_state.user = username
st.success("Logged in successfully!")
else:
st.error(f"Login failed: {response.text}")
def logout():
st.session_state.token = None
st.session_state.user = None
st.success("Logged out!")
def api_call(method, endpoint, params=None, data=None, headers=None):
url = f"{BASE_URL}{endpoint}"
if params:
url += '?' + '&'.join([f"{k}={v}" for k, v in params.items()])
if headers is None:
headers = {}
if st.session_state.token:
headers['Authorization'] = f"Bearer {st.session_state.token}"
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, json=data, headers=headers)
elif method == 'PUT':
response = requests.put(url, json=data, headers=headers)
elif method == 'DELETE':
response = requests.delete(url, headers=headers)
return response
st.title("Clearance System Frontend")
if st.session_state.token is None:
st.header("Login")
username = st.text_input("Username")
password = st.text_input("Password", type="password")
if st.button("Login"):
login(username, password)
else:
st.write(f"Logged in as: {st.session_state.user}")
if st.button("Logout"):
logout()
# Navigation
page = st.sidebar.selectbox("Select Page", [
"Students", "Users", "Tags", "Devices", "Clearance", "RFID", "Scanners", "Profile"
])
if page == "Students":
st.header("Student Management")
action = st.selectbox("Action", ["List", "Create", "Lookup", "Read Single", "Update", "Delete"])
if action == "List":
skip = st.number_input("Skip", min_value=0, value=0)
limit = st.number_input("Limit", min_value=1, value=100)
if st.button("Get Students"):
params = {"skip": skip, "limit": limit}
response = api_call('GET', '/admin/students/', params=params)
if response.status_code == 200:
students = response.json()
st.json(students)
else:
st.error(f"Failed to fetch students: {response.text}")
elif action == "Create":
full_name = st.text_input("Full Name")
matric_no = st.text_input("Matric No")
email = st.text_input("Email")
department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
password = st.text_input("Password", type="password")
if st.button("Create Student"):
data = {
"full_name": full_name,
"matric_no": matric_no,
"email": email,
"department": department,
"password": password
}
response = api_call('POST', '/admin/students/', data=data)
if response.status_code == 201:
st.success("Student created!")
st.json(response.json())
else:
st.error(f"Failed to create student: {response.text}")
elif action == "Lookup":
matric_no = st.text_input("Matric No (optional)")
tag_id = st.text_input("Tag ID (optional)")
if st.button("Lookup Student"):
if not matric_no and not tag_id:
st.error("Provide either Matric No or Tag ID")
else:
params = {}
if matric_no:
params["matric_no"] = matric_no
if tag_id:
params["tag_id"] = tag_id
response = api_call('GET', '/admin/students/lookup', params=params)
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"Failed to lookup student: {response.text}")
elif action == "Read Single":
student_id = st.number_input("Student ID", min_value=1)
if st.button("Get Student"):
response = api_call('GET', f'/admin/students/{student_id}')
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"Failed to fetch student: {response.text}")
elif action == "Update":
student_id = st.number_input("Student ID", min_value=1)
full_name = st.text_input("Full Name (optional)")
email = st.text_input("Email (optional)")
department = st.selectbox("Department (optional)", [None, "Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
if st.button("Update Student"):
data = {}
if full_name:
data["full_name"] = full_name
if email:
data["email"] = email
if department:
data["department"] = department
if not data:
st.error("Provide at least one field to update")
else:
response = api_call('PUT', f'/admin/students/{student_id}', data=data)
if response.status_code == 200:
st.success("Student updated!")
st.json(response.json())
else:
st.error(f"Failed to update student: {response.text}")
elif action == "Delete":
student_id = st.number_input("Student ID", min_value=1)
if st.button("Delete Student"):
response = api_call('DELETE', f'/admin/students/{student_id}')
if response.status_code == 200:
st.success("Student deleted!")
st.json(response.json())
else:
st.error(f"Failed to delete student: {response.text}")
elif page == "Users":
st.header("User Management")
action = st.selectbox("Action", ["List", "Create", "Read Single", "Update", "Delete"])
if action == "List":
skip = st.number_input("Skip", min_value=0, value=0)
limit = st.number_input("Limit", min_value=1, value=100)
if st.button("Get Users"):
params = {"skip": skip, "limit": limit}
response = api_call('GET', '/admin/users/', params=params)
if response.status_code == 200:
users = response.json()
st.json(users)
else:
st.error(f"Failed to fetch users: {response.text}")
elif action == "Create":
username = st.text_input("Username")
email = st.text_input("Email")
full_name = st.text_input("Full Name")
password = st.text_input("Password", type="password")
role = st.selectbox("Role", ["admin", "staff"])
department = st.selectbox("Department (optional)", [None, "Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
if st.button("Create User"):
data = {
"username": username,
"email": email,
"full_name": full_name,
"password": password,
"role": role,
"department": department
}
response = api_call('POST', '/admin/users/', data=data)
if response.status_code == 201:
st.success("User created!")
st.json(response.json())
else:
st.error(f"Failed to create user: {response.text}")
elif action == "Read Single":
user_id = st.number_input("User ID", min_value=1)
if st.button("Get User"):
response = api_call('GET', f'/admin/users/{user_id}')
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"Failed to fetch user: {response.text}")
elif action == "Update":
user_id = st.number_input("User ID", min_value=1)
username = st.text_input("Username (optional)")
email = st.text_input("Email (optional)")
full_name = st.text_input("Full Name (optional)")
password = st.text_input("Password (optional)", type="password")
role = st.selectbox("Role (optional)", [None, "admin", "staff"])
department = st.selectbox("Department (optional)", [None, "Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
if st.button("Update User"):
data = {}
if username:
data["username"] = username
if email:
data["email"] = email
if full_name:
data["full_name"] = full_name
if password:
data["password"] = password
if role:
data["role"] = role
if department:
data["department"] = department
if not data:
st.error("Provide at least one field to update")
else:
response = api_call('PUT', f'/admin/users/{user_id}', data=data)
if response.status_code == 200:
st.success("User updated!")
st.json(response.json())
else:
st.error(f"Failed to update user: {response.text}")
elif action == "Delete":
user_id = st.number_input("User ID", min_value=1)
if st.button("Delete User"):
response = api_call('DELETE', f'/admin/users/{user_id}')
if response.status_code == 200:
st.success("User deleted!")
st.json(response.json())
else:
st.error(f"Failed to delete user: {response.text}")
elif page == "Tags":
st.header("Tag Management")
action = st.selectbox("Action", ["Link", "Unlink"])
if action == "Link":
tag_id = st.text_input("Tag ID")
matric_no = st.text_input("Matric No (for student, optional)")
username = st.text_input("Username (for user, optional)")
if st.button("Link Tag"):
if not matric_no and not username:
st.error("Provide either Matric No or Username")
else:
data = {"tag_id": tag_id}
if matric_no:
data["matric_no"] = matric_no
if username:
data["username"] = username
response = api_call('POST', '/admin/tags/link', data=data)
if response.status_code == 200:
st.success("Tag linked!")
st.json(response.json())
else:
st.error(f"Failed to link tag: {response.text}")
elif action == "Unlink":
tag_id = st.text_input("Tag ID")
if st.button("Unlink Tag"):
response = api_call('DELETE', f'/admin/tags/unlink/{tag_id}')
if response.status_code == 200:
st.success("Tag unlinked!")
st.json(response.json())
else:
st.error(f"Failed to unlink tag: {response.text}")
elif page == "Devices":
st.header("Device Management")
action = st.selectbox("Action", ["List", "Create", "Delete"])
if action == "List":
if st.button("Get Devices"):
response = api_call('GET', '/admin/devices/')
if response.status_code == 200:
devices = response.json()
st.json(devices)
else:
st.error(f"Failed to fetch devices: {response.text}")
elif action == "Create":
device_name = st.text_input("Device Name")
location = st.text_input("Location")
department = st.selectbox("Department", ["Computer Science", "Engineering", "Business Administration", "Law", "Medicine"])
if st.button("Create Device"):
data = {
"device_name": device_name,
"location": location,
"department": department
}
response = api_call('POST', '/admin/devices/', data=data)
if response.status_code == 201:
st.success("Device created!")
st.json(response.json())
else:
st.error(f"Failed to create device: {response.text}")
elif action == "Delete":
device_id = st.number_input("Device ID", min_value=1)
if st.button("Delete Device"):
response = api_call('DELETE', f'/admin/devices/{device_id}')
if response.status_code == 200:
st.success("Device deleted!")
st.json(response.json())
else:
st.error(f"Failed to delete device: {response.text}")
elif page == "Clearance":
st.header("Clearance Management")
matric_no = st.text_input("Matric No")
department = st.selectbox("Department", ["Library", "Student Affairs", "Bursary", "Academic Affairs", "Health Center"])
status = st.selectbox("Status", ["pending", "approved", "rejected"])
remarks = st.text_area("Remarks (optional)")
if st.button("Update Clearance"):
data = {
"matric_no": matric_no,
"department": department,
"status": status,
"remarks": remarks if remarks else None
}
response = api_call('PUT', '/clearance/update', data=data)
if response.status_code == 200:
st.success("Clearance updated!")
st.json(response.json())
else:
st.error(f"Failed to update clearance: {response.text}")
elif page == "RFID":
st.header("RFID Check Status")
tag_id = st.text_input("Tag ID")
if st.button("Check Status"):
data = {"tag_id": tag_id}
headers = {'x-api-key': 'some_api_key_if_needed'} # If required, but backend uses Security
response = api_call('POST', '/rfid/check-status', data=data, headers=headers)
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"Failed to check status: {response.text}")
elif page == "Scanners":
st.header("Scanner Management")
action = st.selectbox("Action", ["Activate", "Retrieve"])
if action == "Activate":
api_key = st.text_input("Device API Key")
if st.button("Activate Scanner"):
data = {"api_key": api_key}
response = api_call('POST', '/rfid/scanners/activate', data=data)
if response.status_code == 204:
st.success("Scanner activated!")
else:
st.error(f"Failed to activate: {response.text}")
elif action == "Retrieve":
if st.button("Retrieve Tag"):
response = api_call('GET', '/rfid/scanners/retrieve')
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"No tag scanned yet: {response.text}")
elif page == "Profile":
st.header("My Profile")
if st.button("Get My Profile"):
response = api_call('GET', '/users/me')
if response.status_code == 200:
st.json(response.json())
else:
st.error(f"Failed to fetch profile: {response.text}")