geethareddy commited on
Commit
c7b5970
·
verified ·
1 Parent(s): ff20512

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +182 -111
app.py CHANGED
@@ -1,124 +1,201 @@
1
  import gradio as gr
2
- import os
 
3
  from simple_salesforce import Salesforce
4
- import pandas as pd
5
- from reportlab.lib.pagesizes import letter
6
- from reportlab.pdfgen import canvas
7
- from io import BytesIO
8
  from dotenv import load_dotenv
9
 
10
- # Load environment variables from .env file
11
  load_dotenv()
12
 
13
- # Salesforce credentials from environment variables
14
- SF_USERNAME = os.getenv('SF_USERNAME')
15
- SF_PASSWORD = os.getenv('SF_PASSWORD')
16
- SF_SECURITY_TOKEN = os.getenv('SF_SECURITY_TOKEN')
17
- SF_DOMAIN = os.getenv('SF_DOMAIN', 'login')
18
-
19
- # Function to generate a PDF report for the supervisor
20
- def generate_pdf_report(supervisor_name, project_id, checklist, suggestions):
21
- file_path = f"reports/{supervisor_name}_{project_id}_report.pdf"
22
-
23
- buffer = BytesIO()
24
- c = canvas.Canvas(buffer, pagesize=letter)
25
- c.drawString(100, 750, f"Supervisor: {supervisor_name}")
26
- c.drawString(100, 735, f"Project ID: {project_id}")
27
-
28
- c.drawString(100, 700, "Daily Checklist:")
29
- y_position = 685
30
- for task in checklist.splitlines():
31
- c.drawString(100, y_position, f"- {task}")
32
- y_position -= 15
33
-
34
- c.drawString(100, y_position - 20, "Focus Suggestions:")
35
- y_position -= 40
36
- for suggestion in suggestions.splitlines():
37
- c.drawString(100, y_position, f"- {suggestion}")
38
- y_position -= 15
39
-
40
- c.showPage()
41
- c.save()
42
- buffer.seek(0)
43
-
44
- with open(file_path, 'wb') as f:
45
- f.write(buffer.read())
46
-
47
- return file_path
48
-
49
- # Function to generate a CSV report
50
- def generate_csv_report(supervisor_name, project_id, checklist, suggestions):
51
- file_path = f"reports/{supervisor_name}_{project_id}_report.csv"
52
-
53
- data = {
54
- "Supervisor": [supervisor_name],
55
- "Project ID": [project_id],
56
- "Checklist": [checklist],
57
- "Suggestions": [suggestions]
58
- }
59
-
60
- df = pd.DataFrame(data)
61
- df.to_csv(file_path, index=False)
62
-
63
- return file_path
64
-
65
- # Function to store the download link in Salesforce
66
- def store_download_link_in_salesforce(supervisor_name, download_link):
67
  try:
68
  sf = Salesforce(
69
- username=SF_USERNAME,
70
- password=SF_PASSWORD,
71
- security_token=SF_SECURITY_TOKEN,
72
- domain=SF_DOMAIN
73
  )
74
- # Query for the supervisor record in the Supervisor_AI_Coaching__c object
75
- result = sf.query(f"SELECT Id FROM Supervisor_AI_Coaching__c WHERE Supervisor_Name__c = '{supervisor_name}' LIMIT 1")
76
-
77
- if result['totalSize'] == 0:
78
- return "Supervisor not found."
79
-
80
- supervisor_ai_coaching_id = result['records'][0]['Id']
81
-
82
- # Update the record with the download link in the Download_Link__c field
83
- sf.Supervisor_AI_Coaching__c.update(supervisor_ai_coaching_id, {
84
- 'Download_Link__c': download_link # Assuming 'Download_Link__c' is the custom field for storing the link
85
- })
86
-
87
- return "Download link stored successfully."
88
-
89
  except Exception as e:
90
- return f"Error storing download link: {e}"
91
-
92
- # Function to generate the report, provide the link, and store it in Salesforce
93
- def generate_and_store_report(role, supervisor_name, project_id, checklist, suggestions, report_type="PDF"):
94
- # Generate the report
95
- if report_type == "PDF":
96
- report_path = generate_pdf_report(supervisor_name, project_id, checklist, suggestions)
97
- else:
98
- report_path = generate_csv_report(supervisor_name, project_id, checklist, suggestions)
99
 
100
- # Create a download link
101
- download_link = f"/static/{report_path}" # Assuming the app is set up to serve static files from the 'static' directory
102
-
103
- # Store the download link in Salesforce
104
- result = store_download_link_in_salesforce(supervisor_name, download_link)
105
-
106
- return download_link, result
 
 
 
 
 
 
 
107
 
108
- # Function to get roles from Salesforce
109
- def get_roles_from_salesforce():
110
  try:
111
  sf = Salesforce(
112
- username=SF_USERNAME,
113
- password=SF_PASSWORD,
114
- security_token=SF_SECURITY_TOKEN,
115
- domain=SF_DOMAIN
116
  )
117
- result = sf.query("SELECT Role__c FROM Supervisor__c WHERE Role__c != NULL")
118
- return list(set(record['Role__c'] for record in result['records']))
 
 
 
 
 
119
  except Exception as e:
120
- print(f"⚠️ Error fetching roles: {e}")
121
- return ["Site Manager", "Safety Officer", "Project Lead"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  # Interface
124
  def create_interface():
@@ -139,12 +216,10 @@ def create_interface():
139
  clear = gr.Button("Clear")
140
  refresh = gr.Button("🔄 Refresh Roles")
141
  dashboard_btn = gr.Button("Dashboard")
142
- report_btn = gr.Button("Download Report")
143
 
144
  checklist_output = gr.Textbox(label="✅ Daily Checklist")
145
  suggestions_output = gr.Textbox(label="💡 Focus Suggestions")
146
  dashboard_link = gr.HTML("")
147
- report_link = gr.HTML("")
148
 
149
  role.change(fn=lambda r: gr.update(choices=get_supervisor_name_by_role(r)), inputs=role, outputs=supervisor_name)
150
  supervisor_name.change(fn=get_projects_for_supervisor, inputs=supervisor_name, outputs=project_id)
@@ -159,10 +234,6 @@ def create_interface():
159
  refresh.click(fn=lambda: gr.update(choices=get_roles_from_salesforce()), outputs=role)
160
 
161
  dashboard_btn.click(fn=open_dashboard, inputs=[role, supervisor_name, project_id], outputs=dashboard_link)
162
-
163
- report_btn.click(fn=generate_and_store_report,
164
- inputs=[role, supervisor_name, project_id, checklist_output, suggestions_output],
165
- outputs=[report_link, gr.HTML("")])
166
 
167
  return demo
168
 
 
1
  import gradio as gr
2
+ import torch
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer
4
  from simple_salesforce import Salesforce
5
+ import os
 
 
 
6
  from dotenv import load_dotenv
7
 
8
+ # Load environment variables
9
  load_dotenv()
10
 
11
+ # Required env vars check
12
+ required_env_vars = ['SF_USERNAME', 'SF_PASSWORD', 'SF_SECURITY_TOKEN']
13
+ missing_vars = [var for var in required_env_vars if not os.getenv(var)]
14
+ if missing_vars:
15
+ raise EnvironmentError(f"Missing required environment variables: {missing_vars}")
16
+
17
+ # Defaults
18
+ KPI_FLAG_DEFAULT = os.getenv('KPI_FLAG', 'True') == 'True'
19
+ ENGAGEMENT_SCORE_DEFAULT = float(os.getenv('ENGAGEMENT_SCORE', '85.0'))
20
+
21
+ # Load model and tokenizer (Updated to use distilgpt2)
22
+ model_name = "distilgpt2" # Using distilgpt2 for faster response
23
+ tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
24
+ model = AutoModelForCausalLM.from_pretrained(model_name, low_cpu_mem_usage=True)
25
+
26
+ if tokenizer.pad_token is None:
27
+ tokenizer.pad_token = tokenizer.eos_token
28
+ tokenizer.pad_token_id = tokenizer.convert_tokens_to_ids(tokenizer.pad_token)
29
+ model.config.pad_token_id = tokenizer.pad_token_id
30
+
31
+ # Refined Prompt to generate day-by-day tasks based on milestones
32
+ PROMPT_TEMPLATE = """You are an AI assistant for construction supervisors. Given the role, project, milestones, and a reflection log, generate:
33
+
34
+ 1. A Daily Checklist with clear and concise tasks based on the role and milestones.
35
+ Split the checklist into day-by-day tasks for a specified time period (e.g., one week).
36
+ 2. Focus Suggestions based on concerns or keywords in the reflection log. Provide at least 2 suggestions.
37
+
38
+ Inputs:
39
+ Role: {role}
40
+ Project ID: {project_id}
41
+ Milestones: {milestones}
42
+ Reflection Log: {reflection}
43
+
44
+ Output Format:
45
+ Checklist (Day-by-Day):
46
+ - Day 1:
47
+ - Task 1
48
+ - Task 2
49
+ - Day 2:
50
+ - Task 1
51
+ - Task 2
52
+ ...
53
+ Suggestions:
54
+ -
55
+ """
56
+
57
+ # Salesforce Functions
58
+ def get_roles_from_salesforce():
 
 
 
 
 
 
59
  try:
60
  sf = Salesforce(
61
+ username=os.getenv('SF_USERNAME'),
62
+ password=os.getenv('SF_PASSWORD'),
63
+ security_token=os.getenv('SF_SECURITY_TOKEN'),
64
+ domain=os.getenv('SF_DOMAIN', 'login')
65
  )
66
+ result = sf.query("SELECT Role__c FROM Supervisor__c WHERE Role__c != NULL")
67
+ return list(set(record['Role__c'] for record in result['records']))
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  except Exception as e:
69
+ print(f"⚠️ Error fetching roles: {e}")
70
+ return ["Site Manager", "Safety Officer", "Project Lead"]
 
 
 
 
 
 
 
71
 
72
+ def get_supervisor_name_by_role(role):
73
+ try:
74
+ sf = Salesforce(
75
+ username=os.getenv('SF_USERNAME'),
76
+ password=os.getenv('SF_PASSWORD'),
77
+ security_token=os.getenv('SF_SECURITY_TOKEN'),
78
+ domain=os.getenv('SF_DOMAIN', 'login')
79
+ )
80
+ role = role.replace("'", "\\'")
81
+ result = sf.query(f"SELECT Name FROM Supervisor__c WHERE Role__c = '{role}'")
82
+ return [record['Name'] for record in result['records']]
83
+ except Exception as e:
84
+ print(f"⚠️ Error fetching supervisor names: {e}")
85
+ return []
86
 
87
+ def get_projects_for_supervisor(supervisor_name):
 
88
  try:
89
  sf = Salesforce(
90
+ username=os.getenv('SF_USERNAME'),
91
+ password=os.getenv('SF_PASSWORD'),
92
+ security_token=os.getenv('SF_SECURITY_TOKEN'),
93
+ domain=os.getenv('SF_DOMAIN', 'login')
94
  )
95
+ supervisor_name = supervisor_name.replace("'", "\\'")
96
+ supervisor_result = sf.query(f"SELECT Id FROM Supervisor__c WHERE Name = '{supervisor_name}' LIMIT 1")
97
+ if supervisor_result['totalSize'] == 0:
98
+ return ""
99
+ supervisor_id = supervisor_result['records'][0]['Id']
100
+ project_result = sf.query(f"SELECT Name FROM Project__c WHERE Supervisor_ID__c = '{supervisor_id}' LIMIT 1")
101
+ return project_result['records'][0]['Name'] if project_result['totalSize'] > 0 else ""
102
  except Exception as e:
103
+ print(f"⚠️ Error fetching project: {e}")
104
+ return ""
105
+
106
+ def field_exists(sf, object_name, field_name):
107
+ try:
108
+ obj_desc = getattr(sf, object_name).describe()
109
+ return field_name in [field['name'] for field in obj_desc['fields']]
110
+ except Exception as e:
111
+ print(f"⚠️ Error checking field {field_name}: {e}")
112
+ return False
113
+
114
+ # New function to generate Salesforce dashboard URL (Visualforce Page)
115
+ def generate_salesforce_dashboard_url(supervisor_name, project_id):
116
+ # Use the provided Salesforce Visualforce URL with supervisorName and projectId as parameters
117
+ return f"https://aicoachforsitesupervisors-dev-ed--c.develop.vf.force.com/apex/DashboardPage?supervisorName={supervisor_name}&projectId={project_id}"
118
+
119
+ # Dashboard button function
120
+ def open_dashboard(role, supervisor_name, project_id):
121
+ # Generate dynamic URL based on supervisor and project
122
+ dashboard_url = generate_salesforce_dashboard_url(supervisor_name, project_id)
123
+ return f'<a href="{dashboard_url}" target="_blank" rel="noopener noreferrer" style="font-size:16px;">Open Salesforce Dashboard</a>'
124
+
125
+ # Generate function
126
+ def generate_outputs(role, supervisor_name, project_id, milestones, reflection):
127
+ if not all([role, supervisor_name, project_id, milestones, reflection]):
128
+ return "❗ Please fill all fields.", ""
129
+
130
+ prompt = PROMPT_TEMPLATE.format(
131
+ role=role,
132
+ project_id=project_id,
133
+ milestones=milestones,
134
+ reflection=reflection
135
+ )
136
+
137
+ inputs = tokenizer(prompt, return_tensors="pt", padding=True, truncation=True, max_length=512)
138
+ try:
139
+ with torch.no_grad():
140
+ outputs = model.generate(
141
+ inputs['input_ids'],
142
+ max_new_tokens=150, # Increased max tokens to capture more content
143
+ no_repeat_ngram_size=2,
144
+ do_sample=True,
145
+ top_p=0.9,
146
+ temperature=0.7,
147
+ pad_token_id=tokenizer.pad_token_id
148
+ )
149
+ result = tokenizer.decode(outputs[0], skip_special_tokens=True)
150
+ except Exception as e:
151
+ print(f"⚠️ Generation error: {e}")
152
+ return "", ""
153
+
154
+ def extract_between(text, start, end):
155
+ s = text.find(start)
156
+ e = text.find(end, s) if end else len(text)
157
+ return text[s + len(start):e].strip() if s != -1 else ""
158
+
159
+ # Extract the checklist and suggestions
160
+ checklist = extract_between(result, "Checklist:\n", "Suggestions:")
161
+ suggestions = extract_between(result, "Suggestions:\n", None)
162
+
163
+ # If checklist or suggestions are empty, generate fallback content
164
+ if not checklist.strip():
165
+ checklist = generate_fallback_checklist(role, milestones)
166
+ if not suggestions.strip():
167
+ suggestions = generate_fallback_suggestions(reflection)
168
+
169
+ return checklist, suggestions
170
+
171
+ # Fallback generation for checklist and suggestions
172
+ def generate_fallback_checklist(role, milestones):
173
+ checklist_items = []
174
+
175
+ # If milestones are provided, add them to the checklist directly
176
+ if milestones and milestones.strip():
177
+ kpis = [kpi.strip() for kpi in milestones.split(",")]
178
+ for kpi in kpis:
179
+ checklist_items.append(f"- Ensure progress on {kpi}")
180
+ else:
181
+ checklist_items.append("- Perform daily safety inspection")
182
+
183
+ return "\n".join(checklist_items)
184
+
185
+ def generate_fallback_suggestions(reflection):
186
+ suggestions_items = []
187
+ reflection_lower = reflection.lower()
188
+ if "student" in reflection_lower or "learning" in reflection_lower:
189
+ suggestions_items.append("- Ensure students are logging incidents consistently")
190
+ suggestions_items.append("- Provide guidance on timely incident recording")
191
+ if "incident" in reflection_lower:
192
+ suggestions_items.append("- Follow up on reported incidents with corrective actions")
193
+
194
+ if not suggestions_items:
195
+ suggestions_items.append("- Monitor team coordination")
196
+ suggestions_items.append("- Review safety protocols with the team")
197
+
198
+ return "\n".join(suggestions_items)
199
 
200
  # Interface
201
  def create_interface():
 
216
  clear = gr.Button("Clear")
217
  refresh = gr.Button("🔄 Refresh Roles")
218
  dashboard_btn = gr.Button("Dashboard")
 
219
 
220
  checklist_output = gr.Textbox(label="✅ Daily Checklist")
221
  suggestions_output = gr.Textbox(label="💡 Focus Suggestions")
222
  dashboard_link = gr.HTML("")
 
223
 
224
  role.change(fn=lambda r: gr.update(choices=get_supervisor_name_by_role(r)), inputs=role, outputs=supervisor_name)
225
  supervisor_name.change(fn=get_projects_for_supervisor, inputs=supervisor_name, outputs=project_id)
 
234
  refresh.click(fn=lambda: gr.update(choices=get_roles_from_salesforce()), outputs=role)
235
 
236
  dashboard_btn.click(fn=open_dashboard, inputs=[role, supervisor_name, project_id], outputs=dashboard_link)
 
 
 
 
237
 
238
  return demo
239