pavansuresh commited on
Commit
5f8a311
·
verified ·
1 Parent(s): acee22d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -44
app.py CHANGED
@@ -1,65 +1,153 @@
1
- import gradio as gr
2
- from salesforce_utils import get_salesforce_objects, get_token, create_record, attach_pdf
3
  from ai_mapping import run_ai_mapping
4
  from ocr_utils import extract_text_from_pdf
5
- import tempfile
6
  import os
 
 
 
 
 
 
7
 
8
- def process_contract(pdf_file, object_name):
9
- if pdf_file is None:
10
- return "❌ No file uploaded.", None
 
 
 
 
 
 
 
 
 
 
11
 
12
- # Get token and Salesforce objects
13
  try:
14
  token, instance_url = get_token()
15
  except Exception as e:
16
  return f"❌ Salesforce authentication failed: {str(e)}", None
17
 
18
- # Step 1: OCR
19
  try:
20
- text_data = extract_text_from_pdf(pdf_file.name) # Use .name to get file path
21
- if not text_data:
22
- return "⚠️ No text extracted from PDF. It may be empty or require OCR.", None
23
  except Exception as e:
24
- return f"❌ Failed to extract text from PDF: {str(e)}", None
25
 
26
- # Step 2: AI Mapping
27
- try:
28
- mappings = run_ai_mapping(text_data)
29
- except Exception as e:
30
- return f"❌ AI mapping failed: {str(e)}", None
 
31
 
32
- # Step 3: Create Salesforce record
33
- try:
34
- record_response = create_record(object_name, mappings, token, instance_url)
35
- if 'id' in record_response:
36
- attach_pdf(record_response['id'], pdf_file.name, token, instance_url)
37
- return f" Record created: {record_response['id']}", mappings
38
- else:
39
- return f"❌ Failed to create record: {record_response}", mappings
40
- except Exception as e:
41
- return f"❌ Failed to create Salesforce record: {str(e)}", mappings
42
 
43
- def get_salesforce_object_names():
44
- try:
45
- token, instance_url = get_token()
46
- objects = get_salesforce_objects(token, instance_url)
47
- return [obj['name'] for obj in objects if obj.get('createable')]
48
- except Exception as e:
49
- return [f"❌ Failed to fetch Salesforce objects: {str(e)}"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- with gr.Blocks() as demo:
52
- gr.Markdown("## 📄 Smart Contract Migrator (Gradio)")
53
 
54
- with gr.Row():
55
- pdf_file = gr.File(label="Upload Contract PDF", file_types=[".pdf"])
56
- object_list = gr.Dropdown(choices=get_salesforce_object_names(), label="Salesforce Object")
57
 
58
- submit_btn = gr.Button("Extract, Map, and Upload")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- output_text = gr.Textbox(label="Status")
61
- output_json = gr.JSON(label="Field Mappings")
 
 
 
 
62
 
63
- submit_btn.click(fn=process_contract, inputs=[pdf_file, object_list], outputs=[output_text, output_json])
 
 
 
 
 
 
 
 
 
 
64
 
65
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from salesforce_utils import get_salesforce_objects, get_salesforce_object_fields, get_token, create_record, attach_pdf
3
  from ai_mapping import run_ai_mapping
4
  from ocr_utils import extract_text_from_pdf
 
5
  import os
6
+ import json
7
+ import tempfile
8
+
9
+ # Initialize session state for failed records
10
+ if 'failed_records' not in st.session_state:
11
+ st.session_state.failed_records = []
12
 
13
+ def save_failed_record(pdf_name, object_name, error, mappings):
14
+ """Log failed records for reconciliation."""
15
+ st.session_state.failed_records.append({
16
+ "pdf_name": pdf_name,
17
+ "object_name": object_name,
18
+ "error": error,
19
+ "mappings": mappings
20
+ })
21
+
22
+ def process_contract(uploaded_files, object_name, manual_mappings):
23
+ """Process uploaded PDFs and create Salesforce records."""
24
+ if not uploaded_files:
25
+ return "❌ No files uploaded.", None
26
 
 
27
  try:
28
  token, instance_url = get_token()
29
  except Exception as e:
30
  return f"❌ Salesforce authentication failed: {str(e)}", None
31
 
32
+ # Get object fields for mapping
33
  try:
34
+ object_fields = get_salesforce_object_fields(token, instance_url, object_name)
35
+ object_field_names = [field['name'] for field in object_fields if field.get('createable')]
 
36
  except Exception as e:
37
+ return f"❌ Failed to fetch object fields: {str(e)}", None
38
 
39
+ results = []
40
+ for pdf_file in uploaded_files:
41
+ pdf_name = pdf_file.name
42
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
43
+ tmp.write(pdf_file.read())
44
+ tmp_path = tmp.name
45
 
46
+ try:
47
+ # Step 1: OCR
48
+ text_data = extract_text_from_pdf(tmp_path)
49
+ if not text_data:
50
+ save_failed_record(pdf_name, object_name, "No text extracted from PDF", {})
51
+ results.append(f"⚠️ {pdf_name}: No text extracted")
52
+ continue
 
 
 
53
 
54
+ # Step 2: AI Mapping
55
+ ai_result = run_ai_mapping(text_data, tmp_path, object_field_names)
56
+ if ai_result['status'] == 'failed':
57
+ save_failed_record(pdf_name, object_name, ai_result['error'], ai_result['mappings'])
58
+ results.append(f"❌ {pdf_name}: {ai_result['error']}")
59
+ continue
60
+
61
+ # Apply manual mappings (if provided)
62
+ mappings = {k: v['value'] for k, v in ai_result['mappings'].items()}
63
+ for field, value in manual_mappings.items():
64
+ if value and field in object_field_names:
65
+ mappings[field] = value
66
+
67
+ # Step 3: Create Salesforce record
68
+ record_response = create_record(object_name, mappings, token, instance_url)
69
+ if 'id' in record_response:
70
+ attach_pdf(record_response['id'], tmp_path, token, instance_url)
71
+ results.append(f"✅ {pdf_name}: Record created (ID: {record_response['id']})")
72
+ else:
73
+ save_failed_record(pdf_name, object_name, f"Failed to create record: {record_response}", mappings)
74
+ results.append(f"❌ {pdf_name}: Failed to create record: {record_response}")
75
+ except Exception as e:
76
+ save_failed_record(pdf_name, object_name, str(e), {})
77
+ results.append(f"❌ {pdf_name}: {str(e)}")
78
+ finally:
79
+ os.unlink(tmp_path)
80
+
81
+ return "\n".join(results), ai_result
82
+
83
+ def retry_failed_record(index, object_name, manual_mappings):
84
+ """Retry a failed record with manual corrections."""
85
+ failed_record = st.session_state.failed_records.pop(index)
86
+ pdf_name = failed_record['pdf_name']
87
+ with open(failed_record['pdf_path'], 'rb') as f:
88
+ result, ai_result = process_contract([f], object_name, manual_mappings)
89
+ return result
90
 
91
+ # Streamlit UI
92
+ st.title("📄 Smart Contract Migrator (Streamlit)")
93
 
94
+ # Epic 1: PDF Upload
95
+ uploaded_files = st.file_uploader("Upload Contract PDFs", type="pdf", accept_multiple_files=True)
 
96
 
97
+ # Epic 2: Salesforce Object Selection
98
+ try:
99
+ token, instance_url = get_token()
100
+ objects = get_salesforce_objects(token, instance_url)
101
+ object_names = [obj['name'] for obj in objects if obj.get('createable')]
102
+ except Exception as e:
103
+ st.error(f"❌ Failed to fetch Salesforce objects: {str(e)}")
104
+ object_names = []
105
+
106
+ object_name = st.selectbox("Select Salesforce Object", object_names)
107
+
108
+ # Display object fields
109
+ if object_name:
110
+ try:
111
+ object_fields = get_salesforce_object_fields(token, instance_url, object_name)
112
+ field_names = [field['name'] for field in object_fields if field.get('createable')]
113
+ st.write("Available Fields:")
114
+ st.write(field_names)
115
+ except Exception as e:
116
+ st.error(f"❌ Failed to fetch fields for {object_name}: {str(e)}")
117
+ field_names = []
118
 
119
+ # Manual mapping input
120
+ manual_mappings = {}
121
+ if field_names:
122
+ st.subheader("Manual Field Mappings (Optional)")
123
+ for field in field_names:
124
+ manual_mappings[field] = st.text_input(f"{field}", "")
125
 
126
+ # Process button
127
+ if st.button("Extract, Map, and Upload"):
128
+ if uploaded_files and object_name:
129
+ status, ai_result = process_contract(uploaded_files, object_name, manual_mappings)
130
+ st.text_area("Status", status)
131
+ if ai_result:
132
+ st.json({
133
+ "mappings": ai_result['mappings'],
134
+ "unmapped_fields": ai_result['unmapped_fields'],
135
+ "status": ai_result['status']
136
+ })
137
 
138
+ # Epic 6: Reconciliation Dashboard
139
+ st.subheader("Reconciliation Dashboard")
140
+ if st.session_state.failed_records:
141
+ for i, record in enumerate(st.session_state.failed_records):
142
+ with st.expander(f"Failed Record: {record['pdf_name']}"):
143
+ st.write(f"Object: {record['object_name']}")
144
+ st.write(f"Error: {record['error']}")
145
+ st.write("Mappings:", record['mappings'])
146
+ manual_mappings_retry = {}
147
+ for field in field_names:
148
+ manual_mappings_retry[field] = st.text_input(f"{field} (Retry)", key=f"retry_{i}_{field}")
149
+ if st.button("Retry", key=f"retry_btn_{i}"):
150
+ result = retry_failed_record(i, record['object_name'], manual_mappings_retry)
151
+ st.write(result)
152
+ else:
153
+ st.write("No failed records.")