# app.py
import streamlit as st
import os
import time
import plotly.express as px
from groq import Groq
from dotenv import load_dotenv
import pycountry
# Load environment variables
load_dotenv()
# Initialize Groq client
try:
client = Groq(api_key=os.getenv("GROQ_API_KEY"))
except:
st.error("Failed to initialize Groq client. Please check your API key.")
st.stop()
# Set up Streamlit page
st.set_page_config(
page_title="LexGuardian",
page_icon="⚖️",
layout="wide",
initial_sidebar_state="collapsed"
)
# Custom CSS for professional styling
st.markdown("""
""", unsafe_allow_html=True)
# Country data with flags
COUNTRIES = {
"🇺🇸 United States": "US",
"🇬🇧 United Kingdom": "GB",
"🇨🇦 Canada": "CA",
"🇦🇺 Australia": "AU",
"🇮🇳 India": "IN",
"🇩🇪 Germany": "DE",
"🇫🇷 France": "FR",
"🇯🇵 Japan": "JP",
"🇧🇷 Brazil": "BR",
"🇿🇦 South Africa": "ZA",
"🇪🇸 Spain": "ES",
"🇸🇬 Singapore": "SG"
}
# Common legal scenarios for students
STUDENT_SCENARIOS = [
"Academic Rights & Responsibilities",
"Campus Housing Issues",
"Discrimination & Harassment",
"Freedom of Speech on Campus",
"Student Privacy Rights",
"Disciplinary Proceedings",
"Financial Aid & Scholarships",
"Intellectual Property Rights",
"Internship & Employment Rights",
"Student Loan Concerns",
"Campus Safety & Security",
"Consumer Protection as a Student"
]
# Student legal topics
LEGAL_TOPICS = [
"Academic Integrity Policies",
"Title IX & Gender Equity",
"Disability Accommodations",
"Student Privacy (FERPA)",
"Campus Free Speech",
"Student Organization Rights",
"Financial Aid Regulations",
"Plagiarism & Copyright",
"Tenant Rights for Students",
"Student Employment Laws",
"Campus Police Interactions",
"Student Loan Borrower Rights"
]
# LLM models available on Groq
MODELS = {
"Llama3-70b (Highest Accuracy)": "llama3-70b-8192",
"Llama3-8b (Fast Response)": "llama3-8b-8192",
"Mixtral-8x7b (Balanced)": "mixtral-8x7b-32768"
}
# Function to get country name from code
def get_country_name(code):
try:
return pycountry.countries.get(alpha_2=code).name
except:
return code
# Function to get rights information from Groq API
def get_legal_rights(country, scenario, model_name):
"""Get legal rights information using Groq API"""
country_name = get_country_name(country)
system_prompt = f"""
You are an expert legal assistant specializing in student rights in {country_name}.
Provide clear, accurate information about student rights in the given scenario.
Guidelines:
- Focus specifically on student rights and responsibilities
- List 5-7 key points as bullet points
- Use plain language understandable to students
- Include relevant legal references when appropriate
- Highlight practical steps students can take
- Mention any country-specific variations
- Keep response under 300 words
- Format with emojis for readability
- End with important disclaimers
"""
user_prompt = f"""
Scenario: {scenario}
Country: {country_name}
Please provide student-specific rights information for this situation in {country_name}.
"""
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_prompt
},
{
"role": "user",
"content": user_prompt
}
],
model=model_name,
temperature=0.3,
max_tokens=1024,
top_p=1,
stream=False,
stop=None,
)
return chat_completion.choices[0].message.content
except Exception as e:
st.error(f"Error fetching data: {str(e)}")
return None
# Function to display response with animation
def display_response(response):
"""Display the response with typing animation effect"""
message_placeholder = st.empty()
full_response = ""
# Simulate stream of response with milliseconds delay
for chunk in response.split():
full_response += chunk + " "
time.sleep(0.03)
# Add a blinking cursor to simulate typing
message_placeholder.markdown(f'
{full_response}▌
', unsafe_allow_html=True)
# Display final message without the cursor
message_placeholder.markdown(f'{response}
', unsafe_allow_html=True)
# Main app
def main():
# Header section
st.markdown("""
""", unsafe_allow_html=True)
# Initialize session state
if 'selected_country' not in st.session_state:
st.session_state.selected_country = "🇺🇸 United States"
if 'selected_scenario' not in st.session_state:
st.session_state.selected_scenario = None
if 'active_tab' not in st.session_state:
st.session_state.active_tab = "explorer"
# Navigation tabs
tab1, tab2, tab3 = st.tabs(["Rights Explorer", "Legal Topics", "Student Resources"])
with tab1:
st.markdown("### ⚖️ Know Your Rights")
st.markdown("Select your country and a situation to understand your legal rights as a student")
# Model selection
model_col = st.columns([1,1,2])
with model_col[0]:
selected_model = st.selectbox("Choose AI Model", list(MODELS.keys()), index=0)
with model_col[1]:
st.markdown(f"**Selected Country:** {st.session_state.selected_country}")
# Main content columns
col1, col2 = st.columns([1, 1.3], gap="large")
with col1:
st.markdown("#### 🌍 Select Your Country")
# Country selection cards
for country_display in COUNTRIES.keys():
is_selected = st.session_state.selected_country == country_display
card_class = "country-card selected" if is_selected else "country-card"
flag, name = country_display.split(" ", 1)
if st.button(
f'{flag} {name}',
key=f"btn_{country_display}",
use_container_width=True
):
st.session_state.selected_country = country_display
st.session_state.selected_scenario = None
st.rerun()
st.markdown("#### 📊 Student Rights Awareness")
countries = list(COUNTRIES.values())
awareness = [85, 82, 80, 78, 75, 83, 81, 79, 76, 74, 80, 77] # Simulated data
fig = px.pie(
names=[get_country_name(code) for code in countries],
values=awareness,
title="Global Student Rights Awareness",
height=300
)
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
margin=dict(l=0, r=0, t=40, b=0),
showlegend=False
)
fig.update_traces(textposition='inside', textinfo='percent+label')
st.plotly_chart(fig, use_container_width=True)
with col2:
st.markdown("#### 🎓 Student Scenarios")
st.markdown("Select a situation relevant to student life")
# Create buttons for each scenario in 2 columns
scenario_cols = st.columns(2)
for i, scenario in enumerate(STUDENT_SCENARIOS):
with scenario_cols[i % 2]:
if st.button(
f"{scenario}",
key=f"scen_{scenario}",
use_container_width=True,
help=f"Click to see student rights for {scenario}"
):
st.session_state.selected_scenario = scenario
# Custom scenario input
custom_scenario = st.text_input(
"**Describe your specific concern:**",
placeholder="e.g., 'Rights during campus protest', 'Academic appeal process'"
)
if custom_scenario:
st.session_state.selected_scenario = custom_scenario
# Response area
if st.session_state.selected_scenario:
country_code = COUNTRIES[st.session_state.selected_country]
with st.spinner(f"🔍 Analyzing student rights for '{st.session_state.selected_scenario}'..."):
response = get_legal_rights(
country_code,
st.session_state.selected_scenario,
MODELS[selected_model]
)
if response:
display_response(response)
else:
st.error("Failed to get response. Please try again.")
else:
st.info("👆 Select a student scenario to see your rights information")
st.markdown("""
Knowledge is your best legal defense
""", unsafe_allow_html=True)
with tab2:
st.markdown("### 📚 Essential Legal Topics for Students")
st.markdown("Explore key legal concepts every student should understand")
# Topics in 3 columns
cols = st.columns(3)
for i, topic in enumerate(LEGAL_TOPICS):
with cols[i % 3]:
with st.expander(f"**{topic}**", expanded=True):
st.info(f"Learn about your rights and responsibilities regarding {topic.lower()}")
if st.button("Explore Topic", key=f"topic_{topic}"):
st.session_state.active_tab = "explorer"
st.session_state.selected_scenario = topic
st.rerun()
st.markdown("### 🧠 Legal Knowledge Quiz")
st.markdown("Test your understanding of student rights")
quiz_cols = st.columns(2)
with quiz_cols[0]:
st.markdown("""
**Question 1:** Can your college share your academic records without permission?
A) Always
B) Only with parents
C) Only with your consent
D) Only in emergencies
""")
answer1 = st.radio("Select answer:", ["A", "B", "C", "D"], key="q1", index=None)
if answer1 == "C":
st.success("Correct! FERPA requires your consent for most record disclosures.")
elif answer1:
st.error("Incorrect. The correct answer is C - Only with your consent.")
with quiz_cols[1]:
st.markdown("""
**Question 2:** What should you do if you face discrimination on campus?
A) Ignore it
B) Report to Title IX coordinator
C) Post about it on social media
D) Confront the person directly
""")
answer2 = st.radio("Select answer:", ["A", "B", "C", "D"], key="q2", index=None)
if answer2 == "B":
st.success("Correct! Reporting to the Title IX coordinator is the proper step.")
elif answer2:
st.error("Incorrect. The correct answer is B - Report to Title IX coordinator.")
with tab3:
st.markdown("### 🛡️ Student Legal Resources")
st.markdown("Essential tools and information for student legal matters")
# Resources in cards
resource_cols = st.columns(3)
resources = [
{"icon": "📝", "title": "Legal Templates", "desc": "Downloadable templates for common student legal documents"},
{"icon": "📚", "title": "Legal Glossary", "desc": "Understand legal terminology with our student-friendly dictionary"},
{"icon": "📱", "title": "Campus Legal Apps", "desc": "Mobile applications for legal assistance on campus"},
{"icon": "👨⚖️", "title": "Find Legal Aid", "desc": "Locate free or low-cost legal services for students"},
{"icon": "📅", "title": "Workshops & Events", "desc": "Upcoming legal education sessions on campus"},
{"icon": "📖", "title": "Legal Handbook", "desc": "Comprehensive guide to student rights and responsibilities"}
]
for i, resource in enumerate(resources):
with resource_cols[i % 3]:
st.markdown(f"""
{resource['icon']}
{resource['title']}
{resource['desc']}
""", unsafe_allow_html=True)
st.markdown("### 📞 Emergency Contacts")
st.markdown("Important contacts for immediate legal assistance")
contacts = st.columns(3)
with contacts[0]:
st.markdown("""
**Campus Security**
Emergency: (555) 123-4567
Non-emergency: (555) 123-4000
""")
with contacts[1]:
st.markdown("""
**Student Legal Services**
Phone: (555) 987-6543
Email: legal@university.edu
""")
with contacts[2]:
st.markdown("""
**National Legal Aid**
Hotline: 1-800-LEGAL-AID
Website: legalaid.org
""")
# Footer
st.markdown("""
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()