AjaykumarPilla commited on
Commit
1af5b00
·
verified ·
1 Parent(s): 7f9e413

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -70
app.py CHANGED
@@ -10,16 +10,37 @@ from reportlab.lib.styles import getSampleStyleSheet
10
  from reportlab.lib.units import inch
11
  from io import BytesIO
12
  from simple_salesforce import Salesforce
13
- import os
14
 
15
- # Salesforce credentials (from environment variables or directly from app.py)
16
- SF_USERNAME = os.getenv('SF_USERNAME', 'your_salesforce_username')
17
- SF_PASSWORD = os.getenv('SF_PASSWORD', 'your_salesforce_password')
18
- SF_SECURITY_TOKEN = os.getenv('SF_SECURITY_TOKEN', 'your_salesforce_security_token')
19
- SF_INSTANCE_URL = os.getenv('SF_INSTANCE_URL', 'https://your_instance.salesforce.com')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- # Initialize Salesforce connection
22
- sf = Salesforce(username=SF_USERNAME, password=SF_PASSWORD, security_token=SF_SECURITY_TOKEN, instance_url=SF_INSTANCE_URL)
 
 
 
23
 
24
  # Function to format high_risk_phases with flag and alert
25
  def format_high_risk_phases(high_risk_phases):
@@ -63,7 +84,6 @@ def generate_pdf(input_data, prediction, heatmap_fig):
63
 
64
  # Prediction Results
65
  story.append(Paragraph("Prediction Results", styles['Heading2']))
66
- # Format high_risk_phases for PDF
67
  high_risk_text = "<br/>".join(format_high_risk_phases(prediction['high_risk_phases']))
68
  prediction_fields = [
69
  f"Delay Probability: {prediction['delay_probability']:.2f}%",
@@ -77,65 +97,45 @@ def generate_pdf(input_data, prediction, heatmap_fig):
77
 
78
  # Heatmap
79
  story.append(Paragraph("Delay Risk Heatmap", styles['Heading2']))
80
- # Save heatmap figure to BytesIO as PNG
81
  img_buffer = BytesIO()
82
  heatmap_fig.savefig(img_buffer, format='png', bbox_inches='tight')
83
  img_buffer.seek(0)
84
- # Embed image in PDF (scale to fit page width)
85
  story.append(Image(img_buffer, width=6*inch, height=2*inch))
86
- plt.close(heatmap_fig) # Close figure to free memory
87
 
88
  doc.build(story)
89
  buffer.seek(0)
90
  return buffer
91
 
92
- # Function to save data in Salesforce custom object (Delay_Predictor__c)
93
  def save_to_salesforce(input_data, prediction):
 
 
94
  try:
95
- # Create record in Delay_Predictor__c object
96
- record = {
97
- 'Project_Name__c': input_data['project_name'],
98
- 'Phase__c': input_data['phase'],
99
- 'Task__c': input_data['task'],
100
- 'Current_Progress__c': input_data['current_progress'],
101
- 'Task_Expected_Duration__c': input_data['task_expected_duration'],
102
- 'Task_Actual_Duration__c': input_data['task_actual_duration'],
103
- 'Workforce_Gap__c': input_data['workforce_gap'],
104
- 'Workforce_Skill_Level__c': input_data['workforce_skill_level'],
105
- 'Workforce_Shift_Hours__c': input_data['workforce_shift_hours'],
106
- 'Weather_Impact_Score__c': input_data['weather_impact_score'],
107
- 'Weather_Condition__c': input_data['weather_condition'],
108
- 'Weather_Forecast_Date__c': input_data['weather_forecast_date'],
109
- 'Delay_Probability__c': prediction['delay_probability'],
110
- 'AI_Insights__c': prediction['ai_insights'],
111
- 'High_Risk_Phases__c': str(prediction['high_risk_phases']), # Storing as a string (can be a complex field if needed)
112
- 'Weather_Condition_Forecast__c': prediction['weather_condition']
113
  }
114
-
115
- # Insert record into Salesforce
116
- sf.Delay_Predictor__c.create(record)
117
- print("Record saved to Salesforce successfully!")
118
  except Exception as e:
119
- print(f"Error saving to Salesforce: {str(e)}")
120
-
121
- # Streamlit app configuration
122
- st.set_page_config(page_title="Delay 🚀", layout="wide")
123
-
124
- # Title
125
- st.title("Project Delay Predictor 🚀")
126
-
127
- # Task options per phase
128
- task_options = {
129
- "Planning": ["Define Scope", "Resource Allocation", "Permit Acquisition"],
130
- "Design": ["Architectural Drafting", "Engineering Analysis", "Design Review"],
131
- "Construction": ["Foundation Work", "Structural Build", "Utility Installation"]
132
- }
133
-
134
- # Initialize session state for phase and task
135
- if 'phase' not in st.session_state:
136
- st.session_state.phase = ""
137
- if 'task' not in st.session_state:
138
- st.session_state.task = ""
139
 
140
  # Input form
141
  with st.form("project_form"):
@@ -145,10 +145,9 @@ with st.form("project_form"):
145
  project_name = st.text_input("Project Name")
146
  phase = st.selectbox("Phase", [""] + ["Planning", "Design", "Construction"], index=0, key="phase_select")
147
 
148
- # Update task options based on phase
149
  if phase != st.session_state.phase:
150
  st.session_state.phase = phase
151
- st.session_state.task = "" # Reset task when phase changes
152
  task_options_list = [""] + task_options.get(phase, []) if phase else [""]
153
  task = st.selectbox("Task", task_options_list, index=0, key="task_select")
154
  current_progress = st.number_input("Current Progress (%)", min_value=0.0, max_value=100.0, step=1.0)
@@ -159,10 +158,8 @@ with st.form("project_form"):
159
  workforce_gap = st.number_input("Workforce Gap (%)", min_value=0.0, max_value=100.0, step=1.0)
160
  workforce_skill_level = st.selectbox("Workforce Skill Level", ["Low", "Medium", "High"], index=1)
161
  workforce_shift_hours = st.number_input("Workforce Shift Hours", min_value=0, step=1, value=8)
162
- # Debug output for shift hours
163
  st.write(f"**Selected Shift Hours**: {workforce_shift_hours}")
164
  weather_impact_score = st.number_input("Weather Impact Score (0-100)", min_value=0, max_value=100, step=1)
165
- # Display computed weather condition
166
  weather_condition = get_weather_condition(weather_impact_score)
167
  st.write(f"**Weather Condition**: {weather_condition}")
168
  weather_forecast_date = st.date_input("Weather Forecast Date", min_value=datetime(2025, 1, 1))
@@ -171,7 +168,6 @@ with st.form("project_form"):
171
 
172
  # Process form submission
173
  if submit_button:
174
- # Prepare input data
175
  input_data = {
176
  "project_name": project_name,
177
  "phase": phase,
@@ -187,19 +183,16 @@ if submit_button:
187
  "weather_forecast_date": weather_forecast_date.strftime("%Y-%m-%d")
188
  }
189
 
190
- # Validate inputs
191
  error = validate_inputs(input_data)
192
  if error:
193
  st.error(error)
194
  else:
195
- # Get prediction
196
  with st.spinner("Predicting..."):
197
  prediction = predict_delay(input_data)
198
 
199
  if "error" in prediction:
200
  st.error(prediction["error"])
201
  else:
202
- # Display results
203
  st.subheader("Prediction Results")
204
  st.write(f"**Delay Probability**: {prediction['delay_probability']:.2f}%")
205
  st.write("**High Risk Phases**:")
@@ -208,14 +201,9 @@ if submit_button:
208
  st.write(f"**AI Insights**: {prediction['ai_insights']}")
209
  st.write(f"**Weather Condition**: {prediction['weather_condition']}")
210
 
211
- # Generate and display heatmap
212
  fig = generate_heatmap(prediction['delay_probability'], f"{phase}: {task}")
213
  st.pyplot(fig)
214
 
215
- # Save to Salesforce after prediction
216
- save_to_salesforce(input_data, prediction)
217
-
218
- # Generate PDF with heatmap and provide download link
219
  pdf_buffer = generate_pdf(input_data, prediction, fig)
220
  st.download_button(
221
  label="Download Prediction Report (PDF)",
@@ -224,6 +212,12 @@ if submit_button:
224
  mime="application/pdf"
225
  )
226
 
227
- # Store prediction in session state
 
 
 
 
 
 
228
  st.session_state.prediction = prediction
229
- st.session_state.input_data = input_data
 
10
  from reportlab.lib.units import inch
11
  from io import BytesIO
12
  from simple_salesforce import Salesforce
 
13
 
14
+ # Streamlit app configuration
15
+ st.set_page_config(page_title="Delay 🚀", layout="wide")
16
+
17
+ # Salesforce connection (using Streamlit secrets)
18
+ try:
19
+ sf = Salesforce(
20
+ username=st.secrets["SF_USERNAME"],
21
+ password=st.secrets["SF_PASSWORD"],
22
+ security_token=st.secrets["SF_SECURITY_TOKEN"],
23
+ instance_url=st.secrets["SF_INSTANCE_URL"]
24
+ )
25
+ except Exception as e:
26
+ st.error(f"Failed to connect to Salesforce: {str(e)}")
27
+ sf = None
28
+
29
+ # Title
30
+ st.title("Project Delay Predictor 🚀")
31
+
32
+ # Task options per phase
33
+ task_options = {
34
+ "Planning": ["Define Scope", "Resource Allocation", "Permit Acquisition"],
35
+ "Design": ["Architectural Drafting", "Engineering Analysis", "Design Review"],
36
+ "Construction": ["Foundation Work", "Structural Build", "Utility Installation"]
37
+ }
38
 
39
+ # Initialize session state for phase and task
40
+ if 'phase' not in st.session_state:
41
+ st.session_state.phase = ""
42
+ if 'task' not in st.session_state:
43
+ st.session_state.task = ""
44
 
45
  # Function to format high_risk_phases with flag and alert
46
  def format_high_risk_phases(high_risk_phases):
 
84
 
85
  # Prediction Results
86
  story.append(Paragraph("Prediction Results", styles['Heading2']))
 
87
  high_risk_text = "<br/>".join(format_high_risk_phases(prediction['high_risk_phases']))
88
  prediction_fields = [
89
  f"Delay Probability: {prediction['delay_probability']:.2f}%",
 
97
 
98
  # Heatmap
99
  story.append(Paragraph("Delay Risk Heatmap", styles['Heading2']))
 
100
  img_buffer = BytesIO()
101
  heatmap_fig.savefig(img_buffer, format='png', bbox_inches='tight')
102
  img_buffer.seek(0)
 
103
  story.append(Image(img_buffer, width=6*inch, height=2*inch))
104
+ plt.close(heatmap_fig)
105
 
106
  doc.build(story)
107
  buffer.seek(0)
108
  return buffer
109
 
110
+ # Function to save data to Salesforce
111
  def save_to_salesforce(input_data, prediction):
112
+ if sf is None:
113
+ return "Salesforce connection not established."
114
  try:
115
+ # Prepare data for Delay_Predictor__c object
116
+ sf_data = {
117
+ "Project_Name__c": input_data["project_name"],
118
+ "Phase__c": input_data["phase"],
119
+ "Task__c": input_data["task"],
120
+ "Current_Progress__c": input_data["current_progress"],
121
+ "Task_Expected_Duration__c": input_data["task_expected_duration"],
122
+ "Task_Actual_Duration__c": input_data["task_actual_duration"],
123
+ "Workforce_Gap__c": input_data["workforce_gap"],
124
+ "Workforce_Skill_Level__c": input_data["workforce_skill_level"],
125
+ "Workforce_Shift_Hours__c": input_data["workforce_shift_hours"],
126
+ "Weather_Impact_Score__c": input_data["weather_impact_score"],
127
+ "Weather_Condition__c": input_data["weather_condition"],
128
+ "Weather_Forecast_Date__c": input_data["weather_forecast_date"],
129
+ "Delay_Probability__c": prediction["delay_probability"],
130
+ "AI_Insights__c": prediction["ai_insights"],
131
+ # Store high_risk_phases as a formatted string
132
+ "High_Risk_Phases__c": "; ".join(format_high_risk_phases(prediction["high_risk_phases"]))
133
  }
134
+ # Create a new record in Delay_Predictor__c
135
+ result = sf.Delay_Predictor__c.create(sf_data)
136
+ return None if result["success"] else f"Salesforce save failed: {result['errors']}"
 
137
  except Exception as e:
138
+ return f"Error saving to Salesforce: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  # Input form
141
  with st.form("project_form"):
 
145
  project_name = st.text_input("Project Name")
146
  phase = st.selectbox("Phase", [""] + ["Planning", "Design", "Construction"], index=0, key="phase_select")
147
 
 
148
  if phase != st.session_state.phase:
149
  st.session_state.phase = phase
150
+ st.session_state.task = ""
151
  task_options_list = [""] + task_options.get(phase, []) if phase else [""]
152
  task = st.selectbox("Task", task_options_list, index=0, key="task_select")
153
  current_progress = st.number_input("Current Progress (%)", min_value=0.0, max_value=100.0, step=1.0)
 
158
  workforce_gap = st.number_input("Workforce Gap (%)", min_value=0.0, max_value=100.0, step=1.0)
159
  workforce_skill_level = st.selectbox("Workforce Skill Level", ["Low", "Medium", "High"], index=1)
160
  workforce_shift_hours = st.number_input("Workforce Shift Hours", min_value=0, step=1, value=8)
 
161
  st.write(f"**Selected Shift Hours**: {workforce_shift_hours}")
162
  weather_impact_score = st.number_input("Weather Impact Score (0-100)", min_value=0, max_value=100, step=1)
 
163
  weather_condition = get_weather_condition(weather_impact_score)
164
  st.write(f"**Weather Condition**: {weather_condition}")
165
  weather_forecast_date = st.date_input("Weather Forecast Date", min_value=datetime(2025, 1, 1))
 
168
 
169
  # Process form submission
170
  if submit_button:
 
171
  input_data = {
172
  "project_name": project_name,
173
  "phase": phase,
 
183
  "weather_forecast_date": weather_forecast_date.strftime("%Y-%m-%d")
184
  }
185
 
 
186
  error = validate_inputs(input_data)
187
  if error:
188
  st.error(error)
189
  else:
 
190
  with st.spinner("Predicting..."):
191
  prediction = predict_delay(input_data)
192
 
193
  if "error" in prediction:
194
  st.error(prediction["error"])
195
  else:
 
196
  st.subheader("Prediction Results")
197
  st.write(f"**Delay Probability**: {prediction['delay_probability']:.2f}%")
198
  st.write("**High Risk Phases**:")
 
201
  st.write(f"**AI Insights**: {prediction['ai_insights']}")
202
  st.write(f"**Weather Condition**: {prediction['weather_condition']}")
203
 
 
204
  fig = generate_heatmap(prediction['delay_probability'], f"{phase}: {task}")
205
  st.pyplot(fig)
206
 
 
 
 
 
207
  pdf_buffer = generate_pdf(input_data, prediction, fig)
208
  st.download_button(
209
  label="Download Prediction Report (PDF)",
 
212
  mime="application/pdf"
213
  )
214
 
215
+ # Save to Salesforce
216
+ sf_error = save_to_salesforce(input_data, prediction)
217
+ if sf_error:
218
+ st.error(sf_error)
219
+ else:
220
+ st.success("Prediction data successfully saved to Salesforce!")
221
+
222
  st.session_state.prediction = prediction
223
+ st.session_state.input_data = input_data