LexGuardian / app.py
sunbal7's picture
Update app.py
314fac4 verified
raw
history blame
12.4 kB
# app.py
import streamlit as st
import pytesseract
from PIL import Image
import fitz # PyMuPDF
import io
import requests
import re
# --- Config ---
API_KEY = "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"
API_URL = "https://openrouter.ai/api/v1/chat/completions"
MODEL = "mistralai/mistral-7b-instruct"
# Set page config
st.set_page_config(
page_title="πŸ”¬ AI Science Lab Assistant",
layout="centered",
page_icon="πŸ”¬"
)
# Custom CSS for styling
st.markdown("""
<style>
.header {
font-size: 36px;
color: #2e86c1;
text-align: center;
padding: 20px;
}
.subheader {
font-size: 24px;
color: #28b463;
border-bottom: 2px solid #f4d03f;
padding-bottom: 10px;
margin-top: 30px;
}
.stButton>button {
background-color: #28b463 !important;
color: white !important;
border-radius: 8px;
padding: 8px 20px;
transition: all 0.3s;
}
.stButton>button:hover {
background-color: #239b56 !important;
transform: scale(1.05);
}
.score-card {
background: linear-gradient(135deg, #e8f8f5, #d1f2eb);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.highlight {
background-color: #f9e79f;
padding: 5px;
border-radius: 5px;
font-weight: bold;
}
.tip-box {
background-color: #eafaf1;
border-left: 5px solid #28b463;
padding: 15px;
margin: 15px 0;
border-radius: 0 8px 8px 0;
}
</style>
""", unsafe_allow_html=True)
# Header
st.markdown('<p class="header">πŸ”¬ AI Science Lab Assistant</p>', unsafe_allow_html=True)
# Introduction
st.markdown("""
<div style="text-align: center; margin-bottom: 30px;">
<p style="font-size: 18px;">Transform your lab reports with AI-powered analysis! Get instant feedback on completeness,
receive improvement suggestions, and ask questions about your scientific work.</p>
</div>
""", unsafe_allow_html=True)
# Features in columns
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("""
<div style="text-align: center;">
<h4>πŸ” Comprehensive Analysis</h4>
<p>Checks for all essential lab report sections</p>
</div>
""", unsafe_allow_html=True)
with col2:
st.markdown("""
<div style="text-align: center;">
<h4>πŸ’― Smart Scoring</h4>
<p>Grades your report on completeness and structure</p>
</div>
""", unsafe_allow_html=True)
with col3:
st.markdown("""
<div style="text-align: center;">
<h4>πŸ“ˆ Improvement Tips</h4>
<p>Personalized suggestions to enhance your report</p>
</div>
""", unsafe_allow_html=True)
# Divider
st.markdown("---")
# --- File Upload ---
st.markdown('<p class="subheader">πŸ“€ Upload Your Lab Report</p>', unsafe_allow_html=True)
uploaded_file = st.file_uploader("Upload image (JPG, PNG) or PDF",
type=["jpg", "jpeg", "png", "pdf"],
label_visibility="collapsed")
lab_text = ""
if uploaded_file:
file_bytes = uploaded_file.read()
file_ext = uploaded_file.name.split(".")[-1].lower()
if file_ext == "pdf":
doc = fitz.open(stream=file_bytes, filetype="pdf")
for page in doc:
lab_text += page.get_text()
else:
image = Image.open(io.BytesIO(file_bytes))
lab_text = pytesseract.image_to_string(image)
# Allow text editing
st.markdown('<p class="subheader">✍️ Extracted Text</p>', unsafe_allow_html=True)
st.caption("Review and edit the extracted text if needed before analysis")
lab_text = st.text_area("", lab_text, height=300, label_visibility="collapsed")
# --- AI Evaluation ---
if lab_text.strip():
# -- AI Evaluation Prompt --
full_prompt = f"""You are a science teacher evaluating a student's lab report. Please provide a comprehensive analysis:
Lab Report:
{lab_text}
Evaluation Guidelines:
1. **Section Check**: Identify which of these sections are present and which are missing:
- Title
- Objective
- Hypothesis
- Materials
- Procedure
- Observations
- Results
- Conclusion
- References
2. **Completeness Score**:
- Assign a numerical score from 1-10 based on completeness
- Justify the score based on missing sections and content quality
3. **Improvement Tips**:
- For each missing section, explain why it's important
- Provide specific suggestions for improvement (e.g., "Try writing a more detailed observation section by including quantitative data")
- Highlight any sections that need more detail or clarity
4. **Structure Response**:
- Start with: "### Missing Sections:"
- Then: "### Completeness Score: X/10"
- Then: "### Improvement Tips:"
- Finally: "### Detailed Feedback:"
Be concise but thorough in your analysis.
"""
def query_ai(prompt):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": "You are a helpful science teacher providing detailed lab report feedback."},
{"role": "user", "content": prompt}
]
}
try:
response = requests.post(API_URL, headers=headers, json=payload, timeout=120)
response.raise_for_status()
return response.json()['choices'][0]['message']['content']
except Exception as e:
st.error(f"Error connecting to AI service: {str(e)}")
return None
if st.button("πŸ§ͺ Analyze Report", use_container_width=True):
with st.spinner("πŸ” Analyzing report with AI. This may take 20-30 seconds..."):
result = query_ai(full_prompt)
if result:
st.success("βœ… Analysis Complete!")
st.balloons()
# Extract score using regex
score_match = re.search(r"Completeness Score:\s*(\d+)/10", result)
score = int(score_match.group(1)) if score_match else None
# Display score in a card
if score is not None:
with st.container():
st.markdown('<div class="score-card">', unsafe_allow_html=True)
# Create columns for score visualization
col1, col2 = st.columns([1, 3])
with col1:
st.markdown(f"<h2 style='text-align: center; color: #28b463;'>{score}/10</h2>",
unsafe_allow_html=True)
st.markdown("<h4 style='text-align: center;'>Completeness Score</h4>",
unsafe_allow_html=True)
with col2:
# Create a color gradient based on score
if score >= 8:
color = "#28b463" # Green
elif score >= 5:
color = "#f39c12" # Orange
else:
color = "#e74c3c" # Red
# Display progress bar with styling
st.progress(score/10, text=f"{score*10}% complete")
st.markdown(
f"<style>"
f".stProgress > div > div > div {{"
f" background-color: {color} !important;"
f" border-radius: 10px;"
f"}}"
f"</style>",
unsafe_allow_html=True
)
st.markdown('</div>', unsafe_allow_html=True)
# Display AI analysis with formatting
st.markdown("## πŸ“ Analysis Results")
# Split sections for better display
sections = {
"Missing Sections": None,
"Improvement Tips": None,
"Detailed Feedback": None
}
current_section = None
for line in result.split('\n'):
if "### Missing Sections:" in line:
current_section = "Missing Sections"
sections[current_section] = []
elif "### Improvement Tips:" in line:
current_section = "Improvement Tips"
sections[current_section] = []
elif "### Detailed Feedback:" in line:
current_section = "Detailed Feedback"
sections[current_section] = []
elif current_section and line.strip():
sections[current_section].append(line)
# Display each section
if sections["Missing Sections"]:
st.markdown("### πŸ” Missing Sections")
missing_text = '\n'.join(sections["Missing Sections"])
st.markdown(f'<div class="highlight">{missing_text}</div>', unsafe_allow_html=True)
if sections["Improvement Tips"]:
st.markdown("### πŸ’‘ Improvement Tips")
tips_text = '\n'.join(sections["Improvement Tips"])
st.markdown(f'<div class="tip-box">{tips_text}</div>', unsafe_allow_html=True)
if sections["Detailed Feedback"]:
st.markdown("### πŸ“‹ Detailed Feedback")
st.write('\n'.join(sections["Detailed Feedback"]))
# Show full AI response in expander
with st.expander("View Full AI Analysis"):
st.markdown(result)
# --- Question Answering Section ---
st.markdown("---")
st.markdown('<p class="subheader">❓ Ask About Your Report</p>', unsafe_allow_html=True)
col1, col2 = st.columns([3, 1])
with col1:
user_question = st.text_input("Ask a question about your lab report",
placeholder="e.g., How can I improve my hypothesis?")
with col2:
st.markdown("<div style='height: 28px;'></div>", unsafe_allow_html=True)
ask_button = st.button("πŸ” Ask Question", use_container_width=True)
if (ask_button or user_question) and user_question.strip():
with st.spinner("Thinking..."):
followup_prompt = f"""Lab Report:
{lab_text}
Question: {user_question}
Answer the question based on the lab report. If the question can't be answered from the report,
suggest what information the student should add to answer it.
"""
followup_response = query_ai(followup_prompt)
if followup_response:
st.markdown("### πŸ’¬ AI Response")
st.markdown(f'<div class="tip-box">{followup_response}</div>', unsafe_allow_html=True)
else:
# Show sample report if no file uploaded
st.markdown("---")
st.markdown('<p class="subheader">πŸ“ Sample Lab Report</p>', unsafe_allow_html=True)
st.markdown("""
**Title:** Effect of Temperature on Enzyme Activity
**Objective:** To investigate how temperature affects catalase enzyme activity
**Hypothesis:** Enzyme activity will increase with temperature up to 37Β°C, then decrease
**Materials:** Test tubes, hydrogen peroxide, liver extract, thermometer
**Procedure:**
1. Prepare test tubes at 5 different temperatures
2. Add equal amounts of hydrogen peroxide and liver extract
3. Measure oxygen production
**Observations:** More bubbles at 37Β°C compared to lower or higher temperatures
**Conclusion:** Enzyme activity peaks at body temperature
""")
st.info("πŸ‘† Upload your own lab report to get a personalized analysis!")