Spaces:
Sleeping
Sleeping
File size: 9,475 Bytes
260b6a6 959ecd0 260b6a6 a91c1bf 260b6a6 775e577 260b6a6 959ecd0 260b6a6 959ecd0 260b6a6 775e577 260b6a6 775e577 260b6a6 959ecd0 260b6a6 a91c1bf 260b6a6 959ecd0 a91c1bf 959ecd0 775e577 260b6a6 775e577 260b6a6 775e577 260b6a6 775e577 260b6a6 775e577 260b6a6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | import streamlit as st
import asyncio
from pathlib import Path
from main import red_flag_analyzer
import fitz
# ============================================================================
# DATA FLOW:
# 1. User uploads .txt or .doc file via Streamlit UI
# 2. File is read and text is extracted
# 3. Text is passed to red_flag_analyzer() from main.py
# 4. red_flag_analyzer() sends text to AI model
# 5. AI analyzes and returns RedFlagReport with identified red flags
# 6. Results are displayed in Streamlit UI with severity color-coding
# ============================================================================
if "show_disclaimer" not in st.session_state:
st.session_state.show_disclaimer = None
# ============================================================================
# PAGE CONFIGURATION
# ============================================================================
st.set_page_config(
page_title="Red Flag Analyzer",
page_icon="π©",
layout="wide",
initial_sidebar_state="expanded"
)
st.title("π© Red Flag Analyzer")
st.markdown("Upload a document to identify potential risks and unfair clauses")
# ============================================================================
# SIDEBAR - FILE UPLOAD
# ============================================================================
st.sidebar.header("π Upload Document")
st.sidebar.markdown("Supported formats: `.txt`, `.docx`, `.pdf`")
# File uploader widget
uploaded_file = st.sidebar.file_uploader(
"Choose a file",
type=["txt", "docx", "pdf"],
help="Upload your document for analysis"
)
# ============================================================================
# FUNCTION: Extract text from uploaded file
# ============================================================================
def extract_text_from_file(uploaded_file):
"""
Extract text from uploaded file based on file type.
Args:
uploaded_file: Streamlit UploadedFile object
Returns:
str: Extracted text from the file
"""
file_extension = Path(uploaded_file.name).suffix.lower() #gets the extension of the file
try:
#checking which extension does it belong
if file_extension == ".txt":
# For .txt files, decode directly
text = uploaded_file.getvalue().decode("utf-8")
return text
if file_extension == ".docx":
from docx import Document
from io import BytesIO
# Extract text from document
doc = Document(BytesIO(uploaded_file.getbuffer()))
text = "\n".join([para.text for para in doc.paragraphs])
return text
if file_extension == ".pdf":
# Ensure the stream buffer is at the beginning
uploaded_file.seek(0)
# Extract text from PDF using PyMuPDF (fitz)
pdf_document = fitz.open(stream=uploaded_file.read(), filetype="pdf")
text = ""
# 'page' is already the loaded page object, no need to re-load it
for page in pdf_document:
text += page.get_text()
pdf_document.close() # Clean up memory handles
return text
except Exception as e:
st.error(f"Error reading file: {str(e)}")
return None
# ============================================================================
# MAIN APP LOGIC
# ============================================================================
if uploaded_file is not None:
# Step 1: Extract text from file
st.sidebar.success(f"β
File uploaded: {uploaded_file.name}")
with st.spinner("π Reading document..."):
document_text = extract_text_from_file(uploaded_file)
if document_text:
# Step 2: Display document preview
st.subheader("π Document Preview")
with st.expander("View full document", expanded=False):
st.text_area(
"Document Content",
value=document_text,
height=200,
disabled=True
)
st.markdown(f"**Document Size:** {len(document_text)} characters")
st.markdown("---")
if st.button("π Analyze for Red Flags", type="primary"):
st.session_state.show_disclaimer=True
if st.session_state.show_disclaimer:
if st.session_state.show_disclaimer==True:
st.warning(
"This tool is designed to assist you in identifying potential "
"risks and red flags in documents. However, it should not be considered legal advice. "
"**Please consult with a qualified legal professional before making any final decisions.** "
"This analysis is for awareness purposes only.",
icon="β οΈ")
if st.checkbox("I understand and wish to proceed with the analysis"):
st.session_state.show_disclaimer=False
with st.spinner("π€ AI is analyzing your document..."):
try:
# Call the red_flag_analyzer function
result = red_flag_analyzer(document_text) #from main.py
# Step 4: Display results
st.success("β
Analysis complete!")
st.markdown("---")
# Display document summary
st.subheader("π Document Summary")
st.info(result.document_summary)
# Display red flags
st.subheader(f"π© Red Flags Found: {len(result.red_flags)}")
#if result returns any red flag
if result.red_flags:
# Color mapping for severity levels
severity_colors = {
"High": "π΄",
"Medium": "π‘",
"Low": "π’"
}
# Display each red flag in a card-like format
for idx, flag in enumerate(result.red_flags, 1):
# Create a container for each red flag
with st.container(border=True):
col1, col2 = st.columns([3, 1])
with col1:
st.markdown(
f"### {severity_colors.get(flag.severity, 'β')} "
f"Red Flag #{idx}"
)
with col2:
st.markdown(
f"**Severity:** `{flag.severity}`"
)
st.markdown("**Problem Text:**")
st.code(flag.item, language="text")
st.markdown("**Why it's a problem:**")
st.write(flag.reason)
st.markdown("---")
else:
st.success("β¨ No red flags found! This document looks good.")
except Exception as e:
st.error(f"β Error during analysis: {str(e)}")
st.info("Make sure your `.env` file is configured with the API key.")
else:
# Show empty state when no file is uploaded
st.info("π Upload a document in the sidebar to get started!")
# Display example
with st.expander("βΉοΈ Example - What kind of red flags will be detected?"):
st.markdown("""
The analyzer looks for:
- **Unfair clauses** (one-sided terms, hidden conditions)
- **Hidden fees** (unexpected costs, surprise charges)
- **High-risk commitments** (unlimited liability, perpetual obligations)
- **Ambiguous rules** (vague language, unclear definitions)
- **Legal risks** (arbitration clauses, waived rights)
""")
# ============================================================================
# FOOTER
# ============================================================================
st.markdown("---")
st.markdown(
"π‘ **Tip:** Use this tool to review contracts, terms of service, and agreements. "
"Always consult with legal professionals for final decisions."
)
|