dissistant / app.py
Stephen Zweibel
Update app for Hugging Face
5d74609
import streamlit as st
import os
import tempfile
from pathlib import Path
import time
import logging
import asyncio
# Import modules
from modules.llm_interface import analyze_with_llm
from modules.report_generator import generate_report
# Import configuration
from config import settings
# Get logger
logger = logging.getLogger(__name__)
# --- Password Authentication Function ---
def check_authentication():
"""Returns `True` if the user is authenticated."""
expected_password = st.secrets.get("APP_PASSWORD")
if not expected_password:
st.session_state.authenticated = True
return True
if "authenticated" not in st.session_state:
st.session_state.authenticated = False
if st.session_state.authenticated:
return True
with st.form(key="password_form"):
st.subheader("Enter Password to Access")
password_attempt = st.text_input("Password", type="password", key="password_input_field")
login_button = st.form_submit_button("Login")
if login_button:
if password_attempt == expected_password:
st.session_state.authenticated = True
st.rerun()
else:
st.error("Incorrect password. Please try again.")
return False
return False
# Set page configuration
st.set_page_config(
page_title="Graduate Center Dissertation Review Tool",
page_icon="📚",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
<style>
.main .block-container {
padding-top: 2rem;
padding-bottom: 2rem;
}
h1, h2, h3 {
margin-bottom: 1rem;
}
.stProgress > div > div > div {
background-color: #4CAF50;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if "analysis_results" not in st.session_state:
st.session_state.analysis_results = None
if "report_generated" not in st.session_state:
st.session_state.report_generated = False
# Title and description
st.title("Graduate Center Dissertation Review Tool")
st.markdown("""
This tool automatically checks dissertations and theses for formatting and citation rules.
Upload your document to receive a detailed report.
""")
# Sidebar for configuration
with st.sidebar:
st.header("Configuration")
# Reset button
if st.button("Start Over"):
for key in st.session_state.keys():
del st.session_state[key]
st.rerun()
if check_authentication():
# Main content area
tab1, tab2 = st.tabs(["Document Upload", "Review Report"])
with tab1:
st.header("Upload Your Document")
uploaded_file = st.file_uploader("Choose a PDF or Word document", type=["pdf", "docx"])
if uploaded_file is not None:
# Display file info
file_details = {
"Filename": uploaded_file.name,
"File size": f"{uploaded_file.size / 1024:.2f} KB",
"File type": uploaded_file.type
}
st.write("File Details:")
for key, value in file_details.items():
st.write(f"- {key}: {value}")
# Process button
if st.button("Process Document"):
logger.info(f"Processing document: {uploaded_file.name}")
try:
with st.spinner("Processing document..."):
# Process document
progress_bar = st.progress(0)
# Step 1: Read file bytes
pdf_bytes = uploaded_file.getvalue()
progress_bar.progress(25)
time.sleep(0.5) # Simulate processing time
# Step 2: Metadata extraction
logger.info("Extracting metadata...")
st.write("Extracting metadata...")
metadata = {"title": uploaded_file.name} # Dummy metadata
progress_bar.progress(50)
time.sleep(0.5) # Simulate processing time
# Step 3: LLM analysis
logger.info("Performing analysis with LLM...")
st.write("Performing analysis with LLM...")
analysis_results = analyze_with_llm(
pdf_file=pdf_bytes,
metadata=metadata
)
st.session_state.analysis_results = analysis_results
progress_bar.progress(100)
# Generate report
logger.info("Generating report...")
st.session_state.report = generate_report(analysis_results)
st.session_state.report_generated = True
# Switch to report tab
st.success("Document processed successfully! View the compliance report in the next tab.")
except Exception as e:
logger.error(f"An error occurred during processing: {str(e)}", exc_info=True)
st.error(f"An error occurred during processing: {str(e)}")
with tab2:
st.header("Review Report")
if not st.session_state.report_generated:
st.info("Upload and process a document to generate a review report.")
else:
# Display summary
st.subheader("Summary")
summary = st.session_state.analysis_results.get("summary", {})
st.write(f"**Overall Assessment**: {summary.get('overall_assessment', 'N/A')}")
st.write(f"**Total Issues**: {summary.get('total_issues', 'N/A')}")
st.write(f"**Critical Issues**: {summary.get('critical_issues', 'N/A')}")
st.write(f"**Warning Issues**: {summary.get('warning_issues', 'N/A')}")
# Display recommendations
st.subheader("Recommendations")
recommendations = st.session_state.analysis_results.get("recommendations", [])
if recommendations:
for rec in recommendations:
st.write(f"- {rec}")
else:
st.write("No recommendations.")
# Display detailed report
st.subheader("Detailed Report")
issues = st.session_state.analysis_results.get("issues", [])
if issues:
for issue in issues:
severity = issue.get('severity', 'N/A').lower()
message = f"**{issue.get('severity', 'N/A').upper()}**: {issue.get('message', 'N/A')}"
if severity == 'critical':
st.error(message)
elif severity == 'warning':
st.warning(message)
elif severity == 'info':
st.info(message)
else:
st.success(message)
st.write(f"**Location**: {issue.get('location', 'N/A')}")
st.write(f"**Suggestion**: {issue.get('suggestion', 'N/A')}")
st.divider()
else:
st.success("No issues found.")
# Footer
st.markdown("---")
st.markdown("© Graduate Center, CUNY. Developed to assist with dissertation and thesis review.")