Update legal_document_analysis.py
Browse files- legal_document_analysis.py +67 -35
legal_document_analysis.py
CHANGED
@@ -15,7 +15,8 @@ from fpdf import FPDF
|
|
15 |
import getpass
|
16 |
import pandas as pd
|
17 |
import seaborn as sns
|
18 |
-
import
|
|
|
19 |
|
20 |
# Load environment variables from .env file
|
21 |
load_dotenv()
|
@@ -169,6 +170,22 @@ def detect_hidden_obligations_or_dependencies(text, summary):
|
|
169 |
|
170 |
return hidden_dependencies
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
# Function to detect risks in the text
|
173 |
def detect_risks(text, summary):
|
174 |
risk_phrases = [
|
@@ -334,12 +351,9 @@ def plot_risk_heatmap(detected_risks):
|
|
334 |
|
335 |
return img_str
|
336 |
|
337 |
-
# Function to
|
338 |
-
def
|
339 |
-
|
340 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
341 |
-
temp_file.write(img_data)
|
342 |
-
return temp_file.name
|
343 |
|
344 |
# Function to generate PDF document with improved aesthetics
|
345 |
def generate_pdf_analysis(document_text, summary, detected_clauses, hidden_obligations, detected_risks, risk_assessment_matrix, risk_level_distribution, risks_by_type, stacked_bar_chart, risk_heatmap):
|
@@ -374,28 +388,38 @@ def generate_pdf_analysis(document_text, summary, detected_clauses, hidden_oblig
|
|
374 |
pdf.cell(0, 10, f"{risk['phrase']}: {risk['summary']} (Risk Level: {risk['risk_level']})", ln=True)
|
375 |
pdf.ln(10)
|
376 |
|
377 |
-
#
|
378 |
-
|
379 |
-
|
380 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
|
382 |
-
|
383 |
-
|
384 |
-
|
|
|
|
|
385 |
|
386 |
-
pdf.image(save_base64_image(risk_heatmap), x=10, y=pdf.get_y(), w=190) # Fit image to width
|
387 |
pdf.ln(10)
|
388 |
|
389 |
-
#
|
390 |
-
pdf
|
391 |
-
pdf.
|
392 |
-
pdf.cell(0, 10, f'Page {pdf.page_no()}', 0, 0, 'C')
|
393 |
|
394 |
-
#
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
|
|
399 |
|
400 |
return pdf_buffer
|
401 |
|
@@ -460,8 +484,11 @@ def send_pdf_via_email(pdf_buffer, recipient_email):
|
|
460 |
msg.attach(MIMEText("Please find the attached analysis of your legal document.", 'plain'))
|
461 |
|
462 |
# Attach the PDF
|
463 |
-
pdf_attachment = io.BytesIO(
|
|
|
|
|
464 |
pdf_attachment.seek(0)
|
|
|
465 |
part = MIMEApplication(pdf_attachment.read(), Name='legal_document_analysis.pdf')
|
466 |
part['Content-Disposition'] = 'attachment; filename="legal_document_analysis.pdf"'
|
467 |
msg.attach(part)
|
@@ -538,7 +565,6 @@ def display_legal_analysis_page():
|
|
538 |
with st.expander(clause['clause'], expanded=False):
|
539 |
st.write(f"*Summary:* {clause['summary']}")
|
540 |
st.write(f"*Context:* {clause['explanation']}")
|
541 |
-
|
542 |
else:
|
543 |
st.write("No key clauses detected.")
|
544 |
|
@@ -588,19 +614,21 @@ def display_legal_analysis_page():
|
|
588 |
for suggestion in suggestions:
|
589 |
st.write(f"- {suggestion}")
|
590 |
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
|
|
600 |
|
601 |
# Download PDF Analysis Button
|
602 |
st.subheader("Download Analysis as PDF")
|
603 |
pdf_buffer = generate_pdf_analysis(document_text, summary, detected_clauses, hidden_obligations, detected_risks, risk_assessment_matrix, risk_level_distribution, risks_by_type, stacked_bar_chart, risk_heatmap)
|
|
|
604 |
|
605 |
# Add download button for PDF
|
606 |
st.download_button(
|
@@ -635,9 +663,13 @@ def display_legal_analysis_page():
|
|
635 |
with st.expander(update['update'], expanded=False):
|
636 |
suggestion = get_update_suggestion(update['update'])
|
637 |
st.write(f"*Suggestion:* {suggestion}")
|
|
|
|
|
|
|
638 |
else:
|
639 |
st.write("No updates detected.")
|
640 |
|
|
|
641 |
# Run the application
|
642 |
if __name__ == "__main__":
|
643 |
display_legal_analysis_page()
|
|
|
15 |
import getpass
|
16 |
import pandas as pd
|
17 |
import seaborn as sns
|
18 |
+
import requests
|
19 |
+
from bs4 import BeautifulSoup
|
20 |
|
21 |
# Load environment variables from .env file
|
22 |
load_dotenv()
|
|
|
170 |
|
171 |
return hidden_dependencies
|
172 |
|
173 |
+
# Function to answer questions about the document
|
174 |
+
def answer_question(question, document_text):
|
175 |
+
prompt = f"The following is a legal document:\n\n{document_text}\n\nBased on this document, answer the following question: {question}"
|
176 |
+
|
177 |
+
try:
|
178 |
+
response = model.invoke(prompt)
|
179 |
+
if hasattr(response, 'content'):
|
180 |
+
answer = response.content
|
181 |
+
else:
|
182 |
+
answer = str(response)
|
183 |
+
|
184 |
+
return answer.strip() if answer else "No answer available."
|
185 |
+
except Exception as e:
|
186 |
+
st.error(f"Error answering question: {str(e)}")
|
187 |
+
return None
|
188 |
+
|
189 |
# Function to detect risks in the text
|
190 |
def detect_risks(text, summary):
|
191 |
risk_phrases = [
|
|
|
351 |
|
352 |
return img_str
|
353 |
|
354 |
+
# Function to convert base64 to image
|
355 |
+
def base64_to_image(data):
|
356 |
+
return io.BytesIO(base64.b64decode(data))
|
|
|
|
|
|
|
357 |
|
358 |
# Function to generate PDF document with improved aesthetics
|
359 |
def generate_pdf_analysis(document_text, summary, detected_clauses, hidden_obligations, detected_risks, risk_assessment_matrix, risk_level_distribution, risks_by_type, stacked_bar_chart, risk_heatmap):
|
|
|
388 |
pdf.cell(0, 10, f"{risk['phrase']}: {risk['summary']} (Risk Level: {risk['risk_level']})", ln=True)
|
389 |
pdf.ln(10)
|
390 |
|
391 |
+
# Save images temporarily and add them to the PDF
|
392 |
+
def save_base64_image(image_str, filename):
|
393 |
+
with open(filename, "wb") as img_file:
|
394 |
+
img_file.write(base64.b64decode(image_str))
|
395 |
+
|
396 |
+
# Save images
|
397 |
+
image_filenames = [
|
398 |
+
"risk_assessment_matrix.png",
|
399 |
+
"risk_level_distribution.png",
|
400 |
+
"risks_by_type.png",
|
401 |
+
"stacked_bar_chart.png",
|
402 |
+
"risk_heatmap.png"
|
403 |
+
]
|
404 |
|
405 |
+
images = [risk_assessment_matrix, risk_level_distribution, risks_by_type, stacked_bar_chart, risk_heatmap]
|
406 |
+
|
407 |
+
for img_str, filename in zip(images, image_filenames):
|
408 |
+
save_base64_image(img_str, filename)
|
409 |
+
pdf.image(filename, x=10, y=pdf.get_y(), w=90) # Use the saved image file
|
410 |
|
|
|
411 |
pdf.ln(10)
|
412 |
|
413 |
+
# Save PDF to a temporary file
|
414 |
+
temp_pdf_path = "legal_document_analysis.pdf"
|
415 |
+
pdf.output(temp_pdf_path, 'F')
|
|
|
416 |
|
417 |
+
# Load the PDF into a BytesIO object
|
418 |
+
with open(temp_pdf_path, "rb") as f:
|
419 |
+
pdf_buffer = io.BytesIO(f.read())
|
420 |
+
|
421 |
+
# Optionally, delete the temporary file
|
422 |
+
os.remove(temp_pdf_path)
|
423 |
|
424 |
return pdf_buffer
|
425 |
|
|
|
484 |
msg.attach(MIMEText("Please find the attached analysis of your legal document.", 'plain'))
|
485 |
|
486 |
# Attach the PDF
|
487 |
+
pdf_attachment = io.BytesIO()
|
488 |
+
pdf_buffer.seek(0)
|
489 |
+
pdf_attachment.write(pdf_buffer.read())
|
490 |
pdf_attachment.seek(0)
|
491 |
+
|
492 |
part = MIMEApplication(pdf_attachment.read(), Name='legal_document_analysis.pdf')
|
493 |
part['Content-Disposition'] = 'attachment; filename="legal_document_analysis.pdf"'
|
494 |
msg.attach(part)
|
|
|
565 |
with st.expander(clause['clause'], expanded=False):
|
566 |
st.write(f"*Summary:* {clause['summary']}")
|
567 |
st.write(f"*Context:* {clause['explanation']}")
|
|
|
568 |
else:
|
569 |
st.write("No key clauses detected.")
|
570 |
|
|
|
614 |
for suggestion in suggestions:
|
615 |
st.write(f"- {suggestion}")
|
616 |
|
617 |
+
# Chatbot Tab
|
618 |
+
st.subheader("🤖 Chatbot")
|
619 |
+
question = st.text_input("Ask a question about the document:")
|
620 |
+
if question:
|
621 |
+
with st.spinner("Getting answer..."):
|
622 |
+
answer = answer_question(question, document_text)
|
623 |
+
if answer:
|
624 |
+
st.write(f"Answer: {answer}")
|
625 |
+
else:
|
626 |
+
st.write("Sorry, I couldn't find an answer to that question.")
|
627 |
|
628 |
# Download PDF Analysis Button
|
629 |
st.subheader("Download Analysis as PDF")
|
630 |
pdf_buffer = generate_pdf_analysis(document_text, summary, detected_clauses, hidden_obligations, detected_risks, risk_assessment_matrix, risk_level_distribution, risks_by_type, stacked_bar_chart, risk_heatmap)
|
631 |
+
pdf_buffer.seek(0)
|
632 |
|
633 |
# Add download button for PDF
|
634 |
st.download_button(
|
|
|
663 |
with st.expander(update['update'], expanded=False):
|
664 |
suggestion = get_update_suggestion(update['update'])
|
665 |
st.write(f"*Suggestion:* {suggestion}")
|
666 |
+
# Additional functionality
|
667 |
+
if st.button(f"Mark '{update['update']}' as addressed"):
|
668 |
+
st.success(f"'{update['update']}' has been marked as addressed.")
|
669 |
else:
|
670 |
st.write("No updates detected.")
|
671 |
|
672 |
+
|
673 |
# Run the application
|
674 |
if __name__ == "__main__":
|
675 |
display_legal_analysis_page()
|