Spaces:
Sleeping
Sleeping
| from flask import Flask, request, jsonify | |
| from transformers import pipeline | |
| from simple_salesforce import Salesforce | |
| import datetime | |
| import logging | |
| app = Flask(__name__) | |
| # Set up logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # Hardcode Salesforce credentials | |
| SF_USERNAME = "app@coach.com" | |
| SF_PASSWORD = "Geetha@1" | |
| SF_SECURITY_TOKEN = "or9hAAcLK7L6cClJjOGwYjbZq" | |
| SF_DOMAIN = "login" | |
| # Initialize Hugging Face model | |
| try: | |
| generator = pipeline("text-generation", model="distilgpt2") | |
| except Exception as e: | |
| logger.error(f"Error initializing Hugging Face model: {str(e)}") | |
| generator = None | |
| # Initialize Salesforce connection with hardcoded credentials | |
| try: | |
| sf = Salesforce( | |
| username=SF_USERNAME, | |
| password=SF_PASSWORD, | |
| security_token=SF_SECURITY_TOKEN, | |
| domain=SF_DOMAIN | |
| ) | |
| except Exception as e: | |
| logger.error(f"Error connecting to Salesforce: {str(e)}") | |
| sf = None | |
| # Add a default route for the root URL | |
| def home(): | |
| logger.info("Received request to root URL") | |
| return jsonify({ | |
| "status": "running", | |
| "message": "This is the AI Coach App backend API. Use the /generate-ai-data endpoint to generate AI coaching data and reports.", | |
| "endpoint": "https://huggingface.co/spaces/varshakolanu/Supervisor/generate-ai-data", | |
| "method": "POST", | |
| "example_payload": { | |
| "supervisor_id": "003xxxxxxxxxxxx", | |
| "project_id": "a0Bxxxxxxxxxxxx", | |
| "supervisor_data": { | |
| "Role__c": "Supervisor", | |
| "Location__c": "New York" | |
| }, | |
| "project_data": { | |
| "Name": "Highway Expansion", | |
| "Start_Date__c": "2025-05-15", | |
| "End_Date__c": "2025-12-31", | |
| "Milestones__c": "Bridge completion by June 1, 2025", | |
| "Project_Schedule__c": "Daily inspections" | |
| } | |
| } | |
| }) | |
| def generate_ai_data(): | |
| """ | |
| Generate AI coaching data and reports based on supervisor and project data. | |
| This endpoint is called by Salesforce when a new project is created or during daily refresh. | |
| Inputs from Salesforce: | |
| - supervisor_id: ID of the supervisor from Supervisor_Profile__c | |
| - project_id: ID of the project from Project_Details__c | |
| - supervisor_data: Contains Role__c, Location__c from Supervisor_Profile__c | |
| - project_data: Contains Name, Start_Date__c, End_Date__c, Milestones__c, Project_Schedule__c from Project_Details__c | |
| Outputs stored in Salesforce: | |
| - AI_Coaching_Data__c: Daily_Checklist__c, Suggested_Tips__c, Risk_Alerts__c, Upcoming_Milestones__c, Performance_Trends__c, Generated_Date__c | |
| - Report_Download__c: Report_Type__c, Report_Data__c, Download_Link__c, Generated_Date__c | |
| """ | |
| logger.info("Received request to /generate-ai-data endpoint") | |
| # Check if dependencies are initialized | |
| if generator is None: | |
| logger.error("Hugging Face model failed to initialize") | |
| return jsonify({ | |
| "status": "error", | |
| "message": "Hugging Face model failed to initialize." | |
| }), 500 | |
| if sf is None: | |
| logger.error("Salesforce connection failed") | |
| return jsonify({ | |
| "status": "error", | |
| "message": "Salesforce connection failed. Check credentials in app.py." | |
| }), 500 | |
| try: | |
| # Extract and validate inputs from the POST request | |
| data = request.get_json() | |
| if not data: | |
| logger.error("No data provided in the request") | |
| return jsonify({ | |
| "status": "error", | |
| "message": "No data provided in the request." | |
| }), 400 | |
| # Required fields | |
| required_fields = ['supervisor_id', 'project_id', 'supervisor_data', 'project_data'] | |
| for field in required_fields: | |
| if field not in data or not data[field]: | |
| logger.error(f"Missing or empty required field: {field}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Missing or empty required field: {field}" | |
| }), 400 | |
| supervisor_id = data['supervisor_id'] | |
| project_id = data['project_id'] | |
| supervisor_data = data['supervisor_data'] | |
| project_data = data['project_data'] | |
| # Validate supervisor_data | |
| required_supervisor_fields = ['Role__c', 'Location__c'] | |
| for field in required_supervisor_fields: | |
| if field not in supervisor_data or not supervisor_data[field]: | |
| logger.error(f"Missing or empty field in supervisor_data: {field}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Missing or empty field in supervisor_data: {field}" | |
| }), 400 | |
| # Validate project_data | |
| required_project_fields = ['Name', 'Start_Date__c', 'End_Date__c', 'Milestones__c', 'Project_Schedule__c'] | |
| for field in required_project_fields: | |
| if field not in project_data or not project_data[field]: | |
| logger.error(f"Missing or empty field in project_data: {field}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Missing or empty field in project_data: {field}" | |
| }), 400 | |
| # Fetch existing checklists to determine progress | |
| try: | |
| checklists = sf.query( | |
| f"SELECT Task_Name__c, Status__c FROM Daily_Checklist__c WHERE Project_ID__c = '{project_id}' AND Date__c = TODAY" | |
| )['records'] | |
| logger.info(f"Fetched {len(checklists)} checklists for project {project_id}") | |
| except Exception as e: | |
| checklists = [] | |
| logger.warning(f"Error querying Daily_Checklist__c: {str(e)}") | |
| completed_tasks = [c['Task_Name__c'] for c in checklists if c.get('Status__c') == 'Completed'] | |
| pending_tasks = [c['Task_Name__c'] for c in checklists if c.get('Status__c') == 'Pending'] | |
| completion_rate = len(completed_tasks) / (len(completed_tasks) + len(pending_tasks)) * 100 if (len(completed_tasks) + len(pending_tasks)) > 0 else 0 | |
| # Construct prompt for AI generation | |
| prompt = ( | |
| f"Generate daily checklist, tips, risk alerts, upcoming milestones, and performance trends for a " | |
| f"{supervisor_data['Role__c']} at {supervisor_data['Location__c']} working on project " | |
| f"{project_data['Name']} with milestones {project_data['Milestones__c']} and schedule " | |
| f"{project_data['Project_Schedule__c']}. " | |
| f"Current completion rate: {completion_rate:.1f}%. Completed tasks: {', '.join(completed_tasks) if completed_tasks else 'None'}. " | |
| f"Pending tasks: {', '.join(pending_tasks) if pending_tasks else 'None'}." | |
| ) | |
| # Generate AI output | |
| try: | |
| ai_response = generator(prompt, max_length=500, num_return_sequences=1)[0]['generated_text'] | |
| logger.info("Successfully generated AI response") | |
| except Exception as e: | |
| logger.error(f"Error generating AI response: {str(e)}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Error generating AI response: {str(e)}" | |
| }), 500 | |
| # Parse AI response (more dynamic parsing based on project progress) | |
| today = "2025-05-22" # Hardcoded to current date (May 22, 2025) | |
| daily_checklist = ( | |
| f"1. Review pending tasks from yesterday (General, Pending)\n" | |
| f"2. Conduct daily safety inspection for {project_data['Name']} (Safety, Pending)\n" | |
| f"3. Schedule progress meeting (General, Pending)" | |
| ) if not pending_tasks else ( | |
| f"1. Complete pending task: {pending_tasks[0]} (General, Pending)\n" | |
| f"2. Conduct daily safety inspection for {project_data['Name']} (Safety, Pending)\n" | |
| f"3. Schedule progress meeting (General, Pending)" | |
| ) | |
| suggested_tips = ( | |
| f"1. Focus on completing pending tasks to improve completion rate.\n" | |
| f"2. Monitor weather conditions in {supervisor_data['Location__c']}.\n" | |
| f"3. Prepare for upcoming milestone." | |
| ) | |
| risk_alerts = f"Risk of delay: Weather risks in {supervisor_data['Location__c']} on {today}." | |
| upcoming_milestones = project_data['Milestones__c'].split(';')[0] if project_data['Milestones__c'] else "No milestones available" | |
| performance_trends = f"Task completion rate: {completion_rate:.1f}% (updated {today})." | |
| # Save AI data to AI_Coaching_Data__c | |
| ai_data = { | |
| 'Supervisor_ID__c': supervisor_id, | |
| 'Project_ID__c': project_id, | |
| 'Daily_Checklist__c': daily_checklist, | |
| 'Suggested_Tips__c': suggested_tips, | |
| 'Risk_Alerts__c': risk_alerts, | |
| 'Upcoming_Milestones__c': upcoming_milestones, | |
| 'Performance_Trends__c': performance_trends, | |
| 'Generated_Date__c': today | |
| } | |
| try: | |
| sf.AI_Coaching_Data__c.create(ai_data) | |
| logger.info(f"Successfully saved AI data to AI_Coaching_Data__c for project {project_id}") | |
| except Exception as e: | |
| logger.error(f"Error saving to AI_Coaching_Data__c: {str(e)}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Error saving to AI_Coaching_Data__c: {str(e)}" | |
| }), 500 | |
| # Generate a report for Report_Download__c | |
| report_data = { | |
| 'Supervisor_ID__c': supervisor_id, | |
| 'Project_ID__c': project_id, | |
| 'Report_Type__c': 'Daily Progress', | |
| 'Report_Data__c': f"Daily Progress Report ({today}): Completion rate: {completion_rate:.1f}%. " | |
| f"Pending tasks: {len(pending_tasks)}. Completed tasks: {len(completed_tasks)}.", | |
| 'Download_Link__c': 'https://your-salesforce-site.com/reports/RPT-' + project_id + '.pdf', # Update with actual Salesforce Site URL | |
| 'Generated_Date__c': today | |
| } | |
| try: | |
| sf.Report_Download__c.create(report_data) | |
| logger.info(f"Successfully saved report to Report_Download__c for project {project_id}") | |
| except Exception as e: | |
| logger.error(f"Error saving to Report_Download__c: {str(e)}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Error saving to Report_Download__c: {str(e)}" | |
| }), 500 | |
| logger.info("Successfully processed request to /generate-ai-data") | |
| return jsonify({ | |
| "status": "success", | |
| "message": "AI data and report generated successfully", | |
| "ai_data": ai_data, | |
| "report_data": report_data | |
| }) | |
| except Exception as e: | |
| logger.error(f"Error generating AI data: {str(e)}") | |
| return jsonify({ | |
| "status": "error", | |
| "message": f"Error generating AI data: {str(e)}" | |
| }), 500 | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860, debug=True) |