Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
import gradio as gr
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
import matplotlib.pyplot as plt
|
@@ -214,11 +213,7 @@ def generate_project_timeline(boq_file, weather, workforce, location, project_ti
|
|
214 |
output_path = os.path.join(temp_dir, output_filename)
|
215 |
logger.debug(f"Gantt chart will be saved to: {output_path}")
|
216 |
|
217 |
-
|
218 |
-
df = pd.read_csv(boq_file.name)
|
219 |
-
else:
|
220 |
-
df = pd.read_csv(boq_file)
|
221 |
-
|
222 |
if "Task Name" not in df.columns or "Duration" not in df.columns:
|
223 |
raise ValueError("CSV must contain 'Task Name' and 'Duration' columns")
|
224 |
|
@@ -247,96 +242,7 @@ def generate_project_timeline(boq_file, weather, workforce, location, project_ti
|
|
247 |
shutil.rmtree(temp_dir)
|
248 |
return None, str(e), None
|
249 |
|
250 |
-
#
|
251 |
-
def gradio_interface(boq_file, weather, workforce, location, project_title):
|
252 |
-
temp_dir = None
|
253 |
-
try:
|
254 |
-
logger.info("Starting gradio_interface...")
|
255 |
-
|
256 |
-
if not boq_file:
|
257 |
-
return None, "Error: No BOQ file uploaded"
|
258 |
-
|
259 |
-
file_path, risk_tags, temp_dir = generate_project_timeline(boq_file, weather, workforce, location, project_title)
|
260 |
-
if not file_path:
|
261 |
-
return None, f"Error: Failed to generate timeline: {risk_tags}"
|
262 |
-
|
263 |
-
if hasattr(boq_file, 'name'):
|
264 |
-
df = pd.read_csv(boq_file.name)
|
265 |
-
else:
|
266 |
-
df = pd.read_csv(boq_file)
|
267 |
-
estimated_duration = sum(df["Duration"])
|
268 |
-
ai_plan_score = min(100, max(0, 100 - (estimated_duration / 100)))
|
269 |
-
logger.debug(f"Estimated duration: {estimated_duration}, AI plan score: {ai_plan_score}")
|
270 |
-
|
271 |
-
record_id = send_to_salesforce(
|
272 |
-
project_title=project_title,
|
273 |
-
gantt_chart_url="",
|
274 |
-
ai_plan_score=ai_plan_score,
|
275 |
-
estimated_duration=estimated_duration,
|
276 |
-
status="Draft",
|
277 |
-
record_id=None,
|
278 |
-
location=location,
|
279 |
-
weather_type=weather
|
280 |
-
)
|
281 |
-
|
282 |
-
if not record_id:
|
283 |
-
return None, f"Error: Failed to create Salesforce record - check logs for details\n\nRisk Tags:\n{risk_tags}"
|
284 |
-
|
285 |
-
boq_file_path = boq_file.name if hasattr(boq_file, 'name') else boq_file
|
286 |
-
work_items_id = upload_file_to_salesforce(boq_file_path, "Boq_data.csv", record_id)
|
287 |
-
if not work_items_id:
|
288 |
-
logger.warning("Failed to upload BOQ file, but proceeding with record creation")
|
289 |
-
|
290 |
-
record_data = {
|
291 |
-
"project_title": project_title,
|
292 |
-
"estimated_duration": estimated_duration,
|
293 |
-
"ai_plan_score": ai_plan_score,
|
294 |
-
"status": "Draft",
|
295 |
-
"risk_tags": risk_tags,
|
296 |
-
}
|
297 |
-
pdf_file = generate_pdf(record_data)
|
298 |
-
if not pdf_file:
|
299 |
-
logger.warning("Failed to generate PDF, but proceeding with record creation")
|
300 |
-
|
301 |
-
pdf_content_id, pdf_url = None, None
|
302 |
-
if pdf_file:
|
303 |
-
pdf_content_id, pdf_url = upload_pdf_to_salesforce(pdf_file, project_title, record_id)
|
304 |
-
if not pdf_content_id:
|
305 |
-
logger.warning("Failed to upload PDF, but proceeding with record creation")
|
306 |
-
|
307 |
-
update_result = send_to_salesforce(
|
308 |
-
project_title=project_title,
|
309 |
-
gantt_chart_url=pdf_url if pdf_url else "",
|
310 |
-
ai_plan_score=ai_plan_score,
|
311 |
-
estimated_duration=estimated_duration,
|
312 |
-
status="Draft",
|
313 |
-
record_id=record_id,
|
314 |
-
location=location,
|
315 |
-
weather_type=weather,
|
316 |
-
work_items_id=work_items_id if work_items_id else ""
|
317 |
-
)
|
318 |
-
if not update_result:
|
319 |
-
logger.warning("Failed to update record with PDF URL, but record was created")
|
320 |
-
|
321 |
-
image_content_id = upload_file_to_salesforce(file_path, f"{project_title}_Gantt_Chart.png", record_id)
|
322 |
-
image_url = None
|
323 |
-
if image_content_id:
|
324 |
-
sf = get_salesforce_connection()
|
325 |
-
if sf:
|
326 |
-
image_url = f"https://{sf.sf_instance}/sfc/servlet.shepherd/version/download/{image_content_id}"
|
327 |
-
logger.debug(f"Generated image URL: {image_url}")
|
328 |
-
|
329 |
-
logger.info("Gradio interface completed successfully.")
|
330 |
-
return image_url if image_url else file_path, f"Successfully created Salesforce record ID: {record_id}\n\nRisk Tags:\n{risk_tags}"
|
331 |
-
except Exception as e:
|
332 |
-
logger.error(f"Error in Gradio interface: {str(e)}", exc_info=True)
|
333 |
-
return None, f"Error in Gradio interface: {str(e)}"
|
334 |
-
finally:
|
335 |
-
if temp_dir and os.path.exists(temp_dir):
|
336 |
-
shutil.rmtree(temp_dir)
|
337 |
-
logger.debug(f"Cleaned up temporary directory: {temp_dir}")
|
338 |
-
|
339 |
-
# Create a FastAPI app and mount the Gradio app with CORS support
|
340 |
app = FastAPI()
|
341 |
app.add_middleware(
|
342 |
CORSMiddleware,
|
@@ -354,7 +260,7 @@ app.mount("/static", StaticFiles(directory=tempfile.gettempdir()), name="static"
|
|
354 |
async def health_check():
|
355 |
return {"status": "healthy"}
|
356 |
|
357 |
-
# FastAPI endpoint for Salesforce
|
358 |
@app.post("/api/gradio_interface")
|
359 |
async def api_gradio_interface(
|
360 |
boq_file: UploadFile = File(...),
|
@@ -454,34 +360,6 @@ async def api_gradio_interface(
|
|
454 |
shutil.rmtree(temp_dir)
|
455 |
logger.debug(f"Cleaned up temporary directory: {temp_dir}")
|
456 |
|
457 |
-
# Create Gradio interface
|
458 |
-
demo = gr.Blocks(theme="default")
|
459 |
-
with demo:
|
460 |
-
gr.Markdown("## AI Civil Work Planner")
|
461 |
-
gr.Markdown("Generate a project timeline (Gantt chart) and risk tags based on BOQ data and site parameters.")
|
462 |
-
|
463 |
-
with gr.Row():
|
464 |
-
with gr.Column():
|
465 |
-
boq_file = gr.File(label="Upload BOQ Data (CSV format)")
|
466 |
-
weather = gr.Dropdown(label="Weather", choices=["sunny", "rainy", "cloudy"], value="sunny")
|
467 |
-
workforce = gr.Number(label="Workforce Size", value=10, precision=0)
|
468 |
-
location = gr.Textbox(label="Location", placeholder="Enter project location")
|
469 |
-
project_title = gr.Textbox(label="Project Title", placeholder="Enter project title")
|
470 |
-
submit_btn = gr.Button("Generate Timeline")
|
471 |
-
|
472 |
-
with gr.Column():
|
473 |
-
output_image = gr.Image(label="Gantt Chart")
|
474 |
-
risk_tags = gr.Textbox(label="Risk Tags and Salesforce Status")
|
475 |
-
|
476 |
-
submit_btn.click(
|
477 |
-
fn=gradio_interface,
|
478 |
-
inputs=[boq_file, weather, workforce, location, project_title],
|
479 |
-
outputs=[output_image, risk_tags],
|
480 |
-
)
|
481 |
-
|
482 |
-
# Mount Gradio app
|
483 |
-
gradio_app = gr.mount_gradio_app(app, demo, path="/")
|
484 |
-
|
485 |
if __name__ == "__main__":
|
486 |
import uvicorn
|
487 |
-
uvicorn.run(
|
|
|
|
|
1 |
import pandas as pd
|
2 |
import numpy as np
|
3 |
import matplotlib.pyplot as plt
|
|
|
213 |
output_path = os.path.join(temp_dir, output_filename)
|
214 |
logger.debug(f"Gantt chart will be saved to: {output_path}")
|
215 |
|
216 |
+
df = pd.read_csv(boq_file)
|
|
|
|
|
|
|
|
|
217 |
if "Task Name" not in df.columns or "Duration" not in df.columns:
|
218 |
raise ValueError("CSV must contain 'Task Name' and 'Duration' columns")
|
219 |
|
|
|
242 |
shutil.rmtree(temp_dir)
|
243 |
return None, str(e), None
|
244 |
|
245 |
+
# Create a FastAPI app with CORS support
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
app = FastAPI()
|
247 |
app.add_middleware(
|
248 |
CORSMiddleware,
|
|
|
260 |
async def health_check():
|
261 |
return {"status": "healthy"}
|
262 |
|
263 |
+
# FastAPI endpoint for processing BOQ files and interacting with Salesforce
|
264 |
@app.post("/api/gradio_interface")
|
265 |
async def api_gradio_interface(
|
266 |
boq_file: UploadFile = File(...),
|
|
|
360 |
shutil.rmtree(temp_dir)
|
361 |
logger.debug(f"Cleaned up temporary directory: {temp_dir}")
|
362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
if __name__ == "__main__":
|
364 |
import uvicorn
|
365 |
+
uvicorn.run(app, host="0.0.0.0", port=7860)
|