Kushalmanda commited on
Commit
c40a2b4
·
verified ·
1 Parent(s): 4cb0d1d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -35
app.py CHANGED
@@ -6,7 +6,6 @@ from word2number import w2n
6
  import re
7
  from typing import Tuple, List, Dict
8
  from simple_salesforce import Salesforce
9
- import os
10
  import base64
11
  from io import BytesIO
12
  import uuid
@@ -16,20 +15,13 @@ from reportlab.lib.pagesizes import letter
16
  from reportlab.pdfgen import canvas
17
  from reportlab.lib.units import inch
18
  import time
 
 
19
 
20
  # Set up logging
21
  logging.basicConfig(level=logging.INFO)
22
  logger = logging.getLogger(__name__)
23
 
24
- # Configuration for public URL base
25
- CONFIG = {
26
- "PUBLIC_URL_BASE": "https://huggingface.co/spaces/YourUsername/YourSpace/resolve/main/static/output/",
27
- "OUTPUT_DIR": "static/output"
28
- }
29
-
30
- # Ensure output directory exists
31
- os.makedirs(CONFIG["OUTPUT_DIR"], exist_ok=True)
32
-
33
  # Custom CSS for styling with dark mode compatibility
34
  css = """
35
  :root {
@@ -223,8 +215,16 @@ body {
223
  transition: all 0.2s ease;
224
  }
225
 
 
 
 
 
 
 
 
 
226
  .count-item:hover {
227
- background-color: rgba(0,0,0,0.05);
228
  transform: translateX(5px);
229
  }
230
 
@@ -256,20 +256,20 @@ button {
256
  button:hover {
257
  background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)) !important;
258
  transform: translateY(-2px) !important;
259
- box-shadow: 0 6px 12px rgba(0,0,0,0.15) !important;
260
  }
261
 
262
  .upload-area {
263
  border: 2px dashed var(--primary-color) !important;
264
- background-color: rgba(240, 248, 255, 0.3) !important;
265
  border-radius: 10px !important;
266
  padding: 30px !important;
267
  transition: all 0.3s ease !important;
268
  }
269
 
270
  .upload-area:hover {
271
- background-color: rgba(224, 255, 255, 0.3) !important;
272
- border-color: var(--secondary-color) !important;
273
  }
274
 
275
  .risk-meter {
@@ -392,11 +392,9 @@ def get_hugging_face_sentiment(text: str) -> float:
392
  logger.error(f"Hugging Face sentiment analysis failed: {str(e)}. Using fallback score.")
393
  return 0.5
394
 
395
- def generate_sentiment_pdf(sentiment_score: float, output_dir: str) -> tuple[str, str, BytesIO]:
396
- """Generate a PDF with sentiment analysis results and return path, URL, and file buffer"""
397
  try:
398
- pdf_filename = f"sentiment_analysis_{int(time.time())}.pdf"
399
- pdf_path = os.path.join(output_dir, pdf_filename)
400
  pdf_file = BytesIO()
401
  c = canvas.Canvas(pdf_file, pagesize=letter)
402
 
@@ -428,16 +426,11 @@ def generate_sentiment_pdf(sentiment_score: float, output_dir: str) -> tuple[str
428
 
429
  c.save()
430
  pdf_file.seek(0)
431
-
432
- with open(pdf_path, "wb") as f:
433
- f.write(pdf_file.getvalue())
434
-
435
- public_url = f"{CONFIG['PUBLIC_URL_BASE']}{pdf_filename}"
436
- logger.info(f"PDF generated: {public_url}")
437
- return pdf_path, public_url, pdf_file
438
  except Exception as e:
439
  logger.error(f"Error generating PDF: {str(e)}")
440
- return "", "", None
441
 
442
  def save_to_salesforce(sf: Salesforce, data: Dict) -> str:
443
  """Save analysis results to Salesforce, return record ID"""
@@ -721,10 +714,16 @@ def analyze_pdf(file_obj) -> List:
721
  salesforce_id = "N/A"
722
 
723
  try:
724
- pdf_path, public_url, pdf_file = generate_sentiment_pdf(sentiment_score, CONFIG["OUTPUT_DIR"])
 
 
 
 
 
 
725
  except Exception as e:
726
  logger.error(f"PDF generation failed: {str(e)}")
727
- public_url = None
728
 
729
  box_class = "success-box" if risk_level == "Low" else "warning-box" if risk_level == "Medium" else "danger-box"
730
  risk_icon = "✅" if risk_level == "Low" else "⚠" if risk_level == "Medium" else "🚨"
@@ -734,7 +733,7 @@ def analyze_pdf(file_obj) -> List:
734
  "High": "This contract is high risk! Immediate legal review required."
735
  }
736
 
737
- # Add sentiment analysis PDF download link
738
  sentiment_analysis_output = f"""
739
  <div class='result-box'>
740
  <div class='section-title'>📊 Sentiment Analysis</div>
@@ -744,8 +743,7 @@ def analyze_pdf(file_obj) -> List:
744
  </div>
745
  {sentiment_meter}
746
  <div style='margin-top: 15px;'>
747
- <strong>Download Sentiment Report:</strong>
748
- {'<a href="' + public_url + '" target="_blank" style="color: var(--primary-color); text-decoration: underline;">Download PDF</a>' if public_url else 'Failed to generate PDF download link'}
749
  </div>
750
  </div>
751
  """
@@ -770,7 +768,8 @@ def analyze_pdf(file_obj) -> List:
770
  obligation_details,
771
  delay_details,
772
  f"<div class='result-box'><div class='section-title'>📜 Extracted Data</div>{extracted_data}</div>",
773
- sentiment_analysis_output
 
774
  ]
775
  except Exception as e:
776
  logger.error(f"Analysis failed: {str(e)}")
@@ -786,7 +785,14 @@ def analyze_pdf(file_obj) -> List:
786
  </div>
787
  </div>
788
  """
789
- return [error_message] * 8
 
 
 
 
 
 
 
790
 
791
  # Create Gradio interface with dark mode compatibility
792
  with gr.Blocks(css=css, title="PDF Contract Risk Analyzer", theme=gr.themes.Default(primary_hue="blue")) as demo:
@@ -833,6 +839,7 @@ with gr.Blocks(css=css, title="PDF Contract Risk Analyzer", theme=gr.themes.Defa
833
 
834
  with gr.Row():
835
  sentiment_analysis = gr.HTML(label="Sentiment Analysis")
 
836
 
837
  submit_btn.click(
838
  fn=analyze_pdf,
@@ -841,7 +848,7 @@ with gr.Blocks(css=css, title="PDF Contract Risk Analyzer", theme=gr.themes.Defa
841
  risk_summary, risk_visualization,
842
  penalty_count, penalty_amounts,
843
  obligation_count, delay_count,
844
- extracted_data, sentiment_analysis
845
  ]
846
  )
847
 
 
6
  import re
7
  from typing import Tuple, List, Dict
8
  from simple_salesforce import Salesforce
 
9
  import base64
10
  from io import BytesIO
11
  import uuid
 
15
  from reportlab.pdfgen import canvas
16
  from reportlab.lib.units import inch
17
  import time
18
+ import tempfile
19
+ import os
20
 
21
  # Set up logging
22
  logging.basicConfig(level=logging.INFO)
23
  logger = logging.getLogger(__name__)
24
 
 
 
 
 
 
 
 
 
 
25
  # Custom CSS for styling with dark mode compatibility
26
  css = """
27
  :root {
 
215
  transition: all 0.2s ease;
216
  }
217
 
218
+ .count-item {
219
+ display: flex;
220
+ justify-content: flex-start;
221
+ align-items: center;
222
+ padding: 10px 0;
223
+ gap: 10px;
224
+ }
225
+
226
  .count-item:hover {
227
+ background-color: rgba(0,255,255,0.05);
228
  transform: translateX(5px);
229
  }
230
 
 
256
  button:hover {
257
  background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)) !important;
258
  transform: translateY(-2px) !important;
259
+ box-shadow: 0 6px 12px rgba(0,0,0,0.15)!important;
260
  }
261
 
262
  .upload-area {
263
  border: 2px dashed var(--primary-color) !important;
264
+ background-color: rgba(240, 248, 255, 0.3)!important;
265
  border-radius: 10px !important;
266
  padding: 30px !important;
267
  transition: all 0.3s ease !important;
268
  }
269
 
270
  .upload-area:hover {
271
+ background-color: rgba(224,255,255,0.3)!important;
272
+ border-color: var(--secondary-color)!important;
273
  }
274
 
275
  .risk-meter {
 
392
  logger.error(f"Hugging Face sentiment analysis failed: {str(e)}. Using fallback score.")
393
  return 0.5
394
 
395
+ def generate_sentiment_pdf(sentiment_score: float) -> BytesIO:
396
+ """Generate a PDF with sentiment analysis results in memory and return BytesIO buffer"""
397
  try:
 
 
398
  pdf_file = BytesIO()
399
  c = canvas.Canvas(pdf_file, pagesize=letter)
400
 
 
426
 
427
  c.save()
428
  pdf_file.seek(0)
429
+ logger.info("PDF generated in memory")
430
+ return pdf_file
 
 
 
 
 
431
  except Exception as e:
432
  logger.error(f"Error generating PDF: {str(e)}")
433
+ return None
434
 
435
  def save_to_salesforce(sf: Salesforce, data: Dict) -> str:
436
  """Save analysis results to Salesforce, return record ID"""
 
714
  salesforce_id = "N/A"
715
 
716
  try:
717
+ pdf_buffer = generate_sentiment_pdf(sentiment_score)
718
+ if pdf_buffer is None:
719
+ raise Exception("Failed to generate PDF")
720
+ # Save to a temporary file for Gradio to serve
721
+ with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as temp_file:
722
+ temp_file.write(pdf_buffer.getvalue())
723
+ temp_file_path = temp_file.name
724
  except Exception as e:
725
  logger.error(f"PDF generation failed: {str(e)}")
726
+ temp_file_path = None
727
 
728
  box_class = "success-box" if risk_level == "Low" else "warning-box" if risk_level == "Medium" else "danger-box"
729
  risk_icon = "✅" if risk_level == "Low" else "⚠" if risk_level == "Medium" else "🚨"
 
733
  "High": "This contract is high risk! Immediate legal review required."
734
  }
735
 
736
+ # Sentiment analysis output with PDF download prompt
737
  sentiment_analysis_output = f"""
738
  <div class='result-box'>
739
  <div class='section-title'>📊 Sentiment Analysis</div>
 
743
  </div>
744
  {sentiment_meter}
745
  <div style='margin-top: 15px;'>
746
+ <strong>Sentiment Report:</strong> {'' if temp_file_path else 'Failed to generate PDF'}
 
747
  </div>
748
  </div>
749
  """
 
768
  obligation_details,
769
  delay_details,
770
  f"<div class='result-box'><div class='section-title'>📜 Extracted Data</div>{extracted_data}</div>",
771
+ sentiment_analysis_output,
772
+ temp_file_path # Return temporary file path for PDF download
773
  ]
774
  except Exception as e:
775
  logger.error(f"Analysis failed: {str(e)}")
 
785
  </div>
786
  </div>
787
  """
788
+ return [error_message] * 9
789
+ finally:
790
+ if temp_file_path and os.path.exists(temp_file_path):
791
+ try:
792
+ os.remove(temp_file_path)
793
+ logger.info(f"Cleaned up temporary PDF file: {temp_file_path}")
794
+ except Exception as e:
795
+ logger.error(f"Failed to clean up temporary PDF file {temp_file_path}: {e}")
796
 
797
  # Create Gradio interface with dark mode compatibility
798
  with gr.Blocks(css=css, title="PDF Contract Risk Analyzer", theme=gr.themes.Default(primary_hue="blue")) as demo:
 
839
 
840
  with gr.Row():
841
  sentiment_analysis = gr.HTML(label="Sentiment Analysis")
842
+ pdf_output = gr.File(label="Download Sentiment Report PDF", file_types=[".pdf"])
843
 
844
  submit_btn.click(
845
  fn=analyze_pdf,
 
848
  risk_summary, risk_visualization,
849
  penalty_count, penalty_amounts,
850
  obligation_count, delay_count,
851
+ extracted_data, sentiment_analysis, pdf_output
852
  ]
853
  )
854