LexGuardian / app.py
sunbal7's picture
Update app.py
e7dc437 verified
raw
history blame
14 kB
# app.py
import streamlit as st
import os
import time
import plotly.express as px
from groq import Groq
from dotenv import load_dotenv
# 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="Legal Rights Explorer Pro",
page_icon="โš–๏ธ",
layout="centered",
initial_sidebar_state="collapsed"
)
# Custom CSS for professional styling
st.markdown("""
<style>
:root {
--primary: #2c3e50;
--secondary: #3498db;
--accent: #1abc9c;
--light: #ecf0f1;
--dark: #2c3e50;
--success: #27ae60;
--card-shadow: 0 6px 20px rgba(0,0,0,0.08);
--transition: all 0.3s ease;
}
.stApp {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
color: #333;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 1000px;
margin: 0 auto;
}
.header {
background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
color: white;
padding: 2.5rem 2rem;
border-radius: 0 0 25px 25px;
box-shadow: var(--card-shadow);
margin-bottom: 2.5rem;
text-align: center;
}
.card {
background: white;
border-radius: 18px;
padding: 2rem;
box-shadow: var(--card-shadow);
margin-bottom: 2rem;
transition: var(--transition);
border-left: 5px solid var(--accent);
}
.card:hover {
box-shadow: 0 12px 30px rgba(0,0,0,0.15);
}
.scenario-btn {
width: 100%;
padding: 1.2rem;
background: linear-gradient(135deg, var(--secondary) 0%, #2980b9 100%);
color: white;
border: none;
border-radius: 15px;
font-weight: 600;
margin: 0.8rem 0;
cursor: pointer;
transition: var(--transition);
text-align: left;
padding-left: 25px;
font-size: 1.1rem;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.scenario-btn:hover {
background: linear-gradient(135deg, var(--primary) 0%, #2c3e50 100%);
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0,0,0,0.15);
}
.response-card {
background: white;
border-left: 5px solid var(--success);
border-radius: 15px;
padding: 2.5rem;
margin-top: 2.5rem;
box-shadow: var(--card-shadow);
animation: fadeIn 0.8s ease;
}
.country-card {
display: flex;
align-items: center;
gap: 15px;
padding: 1.5rem;
border-radius: 15px;
background: white;
box-shadow: var(--card-shadow);
margin-bottom: 18px;
cursor: pointer;
transition: var(--transition);
border: 2px solid transparent;
}
.country-card:hover {
transform: translateX(8px);
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}
.country-card.selected {
background: linear-gradient(135deg, var(--light) 0%, #d6eaf8 100%);
border: 2px solid var(--accent);
box-shadow: 0 8px 25px rgba(0,0,0,0.12);
}
.footer {
text-align: center;
padding: 2.5rem;
margin-top: 3.5rem;
color: var(--dark);
font-size: 1rem;
background: rgba(236, 240, 241, 0.7);
border-radius: 20px;
box-shadow: var(--card-shadow);
}
.spinner {
display: flex;
justify-content: center;
margin: 3rem 0;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.pulse {
animation: pulse 2s infinite;
}
@media (max-width: 768px) {
.header {
padding: 1.8rem 1.2rem;
}
.card {
padding: 1.5rem;
}
.scenario-btn {
padding: 1rem;
font-size: 1rem;
}
}
</style>
""", unsafe_allow_html=True)
# Country data with flags
COUNTRIES = {
"๐Ÿ‡บ๐Ÿ‡ธ United States": "US",
"๐Ÿ‡ฌ๐Ÿ‡ง United Kingdom": "UK",
"๐Ÿ‡จ๐Ÿ‡ฆ Canada": "CA",
"๐Ÿ‡ฆ๐Ÿ‡บ Australia": "AU",
"๐Ÿ‡ฎ๐Ÿ‡ณ India": "IN",
"๐Ÿ‡ฉ๐Ÿ‡ช Germany": "DE",
"๐Ÿ‡ซ๐Ÿ‡ท France": "FR",
"๐Ÿ‡ฏ๐Ÿ‡ต Japan": "JP",
"๐Ÿ‡ง๐Ÿ‡ท Brazil": "BR",
"๐Ÿ‡ฟ๐Ÿ‡ฆ South Africa": "ZA",
"๐Ÿ‡ช๐Ÿ‡ธ Spain": "ES",
"๐Ÿ‡ธ๐Ÿ‡ฌ Singapore": "SG"
}
# Common legal scenarios
SCENARIOS = [
"Traffic Stop by Police",
"Workplace Discrimination",
"Rental Housing Issues",
"Medical Emergency Rights",
"Consumer Protection",
"Arrest or Detention",
"Border Crossing",
"Online Privacy",
"Employment Termination",
"Debt Collection",
"Freedom of Speech",
"Immigration Rights"
]
# LLM models available on Groq
MODELS = {
"Llama3-70b (Best)": "llama3-70b-8192",
"Llama3-8b (Fast)": "llama3-8b-8192",
"Mixtral-8x7b": "mixtral-8x7b-32768"
}
# Function to get rights information from Groq API
def get_legal_rights(country, scenario, model_name):
"""Get legal rights information using Groq API"""
system_prompt = f"""
You are an expert legal assistant specializing in {country} law.
Provide clear, accurate information about an individual's rights in the given scenario.
Guidelines:
- List 5-7 key rights as bullet points
- Start with a brief context about the legal situation
- Use plain language understandable to non-lawyers
- Include relevant legal references when appropriate
- Highlight any critical actions the person should take
- Mention any country-specific variations
- Keep response under 350 words
- Format with emojis for readability
- End with important disclaimers
"""
user_prompt = f"""
Scenario: {scenario}
Country: {country}
Please provide a comprehensive list of rights for this situation in {country}.
"""
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'<div class="response-card">{full_response}โ–Œ</div>', unsafe_allow_html=True)
# Display final message without the cursor
message_placeholder.markdown(f'<div class="response-card">{response}</div>', unsafe_allow_html=True)
# Main app
def main():
# Header section
st.markdown("""
<div class="header">
<h1 style="margin:0;font-size:2.8rem;">Legal Rights Explorer Pro</h1>
<p style="margin:0;font-size:1.3rem;opacity:0.9;margin-top:12px;">Know your rights โ€ข Protect your freedom</p>
</div>
""", 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
# Model selection at top
st.markdown("### โš™๏ธ AI Model Selection")
model_cols = st.columns(3)
with model_cols[0]:
selected_model = st.selectbox("Choose AI Model", list(MODELS.keys()), index=0)
with model_cols[1]:
st.markdown("### ๐ŸŒŽ Country")
st.caption("Selected: " + st.session_state.selected_country)
# Main content columns
col1, col2 = st.columns([1, 1.2], gap="large")
with col1:
st.markdown("### ๐ŸŒ Select Your Country")
st.markdown("Choose your country to see jurisdiction-specific rights information")
# Country selection cards
for country_display in COUNTRIES.keys():
is_selected = st.session_state.selected_country == country_display
# Use button to capture click
if st.button(country_display,
key=f"btn_{country_display}",
use_container_width=True,
type="primary" if is_selected else "secondary"):
st.session_state.selected_country = country_display
st.rerun()
# Country visualization
st.markdown("### ๐Ÿ“Š Global Rights Index")
countries = list(COUNTRIES.values())
awareness = [92, 89, 87, 85, 82, 88, 86, 84, 79, 81, 85, 83] # Simulated data
fig = px.bar(
x=countries,
y=awareness,
labels={'x': 'Country', 'y': 'Rights Awareness'},
color=awareness,
color_continuous_scale='Teal',
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=30, b=0)
)
st.plotly_chart(fig, use_container_width=True)
# Legal resources
with st.expander("๐Ÿ“š Legal Resources & References"):
st.markdown("""
- [United Nations Human Rights](https://www.ohchr.org/)
- [International Justice Resource Center](https://ijrcenter.org/)
- [Global Legal Information Network](https://www.loc.gov/law/help/legal-info.php)
- [World Legal Information Institute](https://www.worldlii.org/)
- [Amnesty International](https://www.amnesty.org/)
""")
with col2:
st.markdown("### ๐Ÿšจ Select a Legal Scenario")
st.markdown("Choose a situation to understand your rights and protections")
# Create buttons for each scenario
cols = st.columns(2)
for i, scenario in enumerate(SCENARIOS):
with cols[i % 2]:
if st.button(
f"**{scenario}**",
key=scenario,
use_container_width=True,
help=f"Click to see your rights for {scenario}"
):
st.session_state.selected_scenario = scenario
# Custom scenario input
custom_scenario = st.text_input("**Or describe your specific situation:**", placeholder="e.g., 'Rights during home search', 'Employee privacy rights'")
if custom_scenario:
st.session_state.selected_scenario = custom_scenario
# Response area
st.markdown("### โš–๏ธ Your Legal Rights Analysis")
if st.session_state.selected_scenario:
country_code = COUNTRIES[st.session_state.selected_country]
with st.spinner(f"๐Ÿ” Analyzing your rights for '{st.session_state.selected_scenario}' in {country_code}..."):
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("๐Ÿ‘† Please select a legal scenario to see your rights information")
st.image("https://images.unsplash.com/photo-1589391886645-d51941baf7fb?auto=format&fit=crop&w=600&h=400",
caption="Know Your Rights, Exercise Your Freedom")
st.markdown("""
<div class="card">
<h3>Why Know Your Rights?</h3>
<p>Understanding your legal rights empowers you to:</p>
<ul>
<li>Protect yourself in difficult situations</li>
<li>Make informed decisions when facing legal issues</li>
<li>Prevent exploitation and rights violations</li>
<li>Access justice when your rights are infringed</li>
<li>Confidently navigate complex legal systems</li>
</ul>
<p style="margin-top:15px;font-style:italic;">"Knowledge of the law is the first defense against injustice."</p>
</div>
""", unsafe_allow_html=True)
# Footer
st.markdown("""
<div class="footer">
<h4>Legal Rights Explorer Pro</h4>
<p>ยฉ 2023 โ€ข For Educational Purposes Only โ€ข Not Legal Advice</p>
<p style="font-size:0.9rem;margin-top:10px;">Always consult a qualified attorney in your jurisdiction for your specific legal situation</p>
<p style="font-size:0.8rem;opacity:0.7;margin-top:15px;">Powered by Groq Cloud & Open-Source LLMs</p>
</div>
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()