lokeshloki143's picture
Update app.py
b6ca777 verified
import requests
import json
import logging
from datetime import datetime
from simple_salesforce import Salesforce
from flask import Flask, jsonify, request, render_template, redirect, url_for
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Hugging Face API configuration
HUGGING_FACE_API_URL = "https://api-inference.huggingface.co/models/distilgpt2"
HUGGING_FACE_API_TOKEN = "your_hugging_face_api_token_here" # Replace with your actual Hugging Face API token
# Salesforce configuration
SALESFORCE_USERNAME = "[email protected]"
SALESFORCE_PASSWORD = "Teja90325@"
SALESFORCE_SECURITY_TOKEN = "clceSdBgQ30Rx9BSC66gAcRx"
SALESFORCE_DOMAIN = "login.salesforce.com"
# Validate configuration
if not HUGGING_FACE_API_TOKEN:
logger.error("HUGGING_FACE_API_TOKEN is not set")
raise ValueError("HUGGING_FACE_API_TOKEN must be provided")
if not HUGGING_FACE_API_URL.startswith("https://api-inference.huggingface.co/models/"):
logger.error("Invalid HUGGING_FACE_API_URL: %s", HUGGING_FACE_API_URL)
raise ValueError("HUGGING_FACE_API_URL must point to a valid Hugging Face model")
if not all([SALESFORCE_USERNAME, SALESFORCE_PASSWORD, SALESFORCE_SECURITY_TOKEN]):
logger.error("Salesforce credentials are incomplete")
raise ValueError("Salesforce credentials must be set")
# Initialize Flask app
app = Flask(__name__)
def generate_coaching_output(data):
"""
Generate daily checklist and tips using Hugging Face LLM.
"""
logger.info("Generating coaching output for supervisor %s", data['supervisor_id'])
milestones_json = json.dumps(data['milestones'], indent=2)
prompt = f"""
You are an AI Coach for construction site supervisors. Based on the following data, generate a daily checklist, three focus tips, and a motivational quote. Ensure outputs are concise, actionable, and tailored to the supervisor's role, project status, and reflection log.
Supervisor Role: {data['role']}
Project Milestones: {milestones_json}
Reflection Log: {data['reflection_log']}
Weather: {data['weather']}
Format the response as JSON:
{{
"checklist": ["item1", "item2", ...],
"tips": ["tip1", "tip2", "tip3"],
"quote": "motivational quote"
}}
"""
headers = {
"Authorization": f"Bearer {HUGGING_FACE_API_TOKEN}",
"Content-Type": "application/json"
}
payload = {
"inputs": prompt,
"parameters": {
"max_length": 200,
"temperature": 0.7,
"top_p": 0.9
}
}
try:
response = requests.post(HUGGING_FACE_API_URL, headers=headers, json=payload, timeout=5)
response.raise_for_status()
result = response.json()
generated_text = result[0]["generated_text"] if isinstance(result, list) else result["generated_text"]
start_idx = generated_text.find('{')
end_idx = generated_text.rfind('}') + 1
if start_idx == -1 or end_idx == 0:
logger.error("No valid JSON found in LLM output")
raise ValueError("No valid JSON found in LLM output")
json_str = generated_text[start_idx:end_idx]
output = json.loads(json_str)
logger.info("Successfully generated coaching output")
return output
except requests.exceptions.HTTPError as e:
logger.error("Hugging Face API HTTP error: %s", e)
return None
except (json.JSONDecodeError, ValueError) as e:
logger.error("Error parsing LLM output: %s", e)
return None
except Exception as e:
logger.error("Unexpected error in Hugging Face API call: %s", e)
return None
def save_to_salesforce(output, supervisor_id, project_id):
"""
Save coaching output to Salesforce Supervisor_AI_Coaching__c object.
"""
if not output:
logger.error("No coaching output to save")
return False
try:
sf = Salesforce(
username=SALESFORCE_USERNAME,
password=SALESFORCE_PASSWORD,
security_token=SALESFORCE_SECURITY_TOKEN,
domain=SALESFORCE_DOMAIN
)
logger.info("Connected to Salesforce")
coaching_record = {
"Supervisor_ID__c": supervisor_id,
"Project_ID__c": project_id,
"Daily_Checklist__c": "\n".join(output["checklist"]),
"Suggested_Tips__c": "\n".join(output["tips"]),
"Quote__c": output["quote"],
"Generated_Date__c": datetime.now().strftime("%Y-%m-%d")
}
sf.Supervisor_AI_Coaching__c.upsert(
f"Supervisor_ID__c/{supervisor_id}_{datetime.now().strftime('%Y-%m-%d')}",
coaching_record
)
logger.info("Successfully saved coaching record to Salesforce for supervisor %s", supervisor_id)
return True
except Exception as e:
logger.error("Salesforce error: %s", e)
return False
def fetch_salesforce_data(supervisor_id, project_id):
"""
Fetch coaching data from Salesforce for a given supervisor and project.
"""
try:
sf = Salesforce(
username=SALESFORCE_USERNAME,
password=SALESFORCE_PASSWORD,
security_token=SALESFORCE_SECURITY_TOKEN,
domain=SALESFORCE_DOMAIN
)
logger.info("Connected to Salesforce for data fetch")
query = f"""
SELECT Daily_Checklist__c, Suggested_Tips__c, Quote__c, Generated_Date__c
FROM Supervisor_AI_Coaching__c
WHERE Supervisor_ID__c = '{supervisor_id}' AND Project_ID__c = '{project_id}'
ORDER BY Generated_Date__c DESC
LIMIT 1
"""
result = sf.query(query)
if result['totalSize'] > 0:
record = result['records'][0]
return {
'checklist': record['Daily_Checklist__c'].split('\n') if record['Daily_Checklist__c'] else [],
'tips': record['Suggested_Tips__c'].split('\n') if record['Suggested_Tips__c'] else [],
'quote': record['Quote__c'] or ''
}
else:
logger.info("No coaching data found for supervisor %s and project %s", supervisor_id, project_id)
return None
except Exception as e:
logger.error("Salesforce fetch error: %s", e)
return None
@app.route('/', methods=['GET'])
def redirect_to_ui():
"""
Redirect root URL to the UI.
"""
return redirect(url_for('ui'))
@app.route('/ui', methods=['GET', 'POST'])
def ui():
"""
Serve the HTML user interface and handle form submissions.
"""
form_data = {}
output = {}
error = ""
if request.method == 'POST':
action = request.form.get('action')
form_data = {
'supervisor_id': request.form.get('supervisor_id', ''),
'role': request.form.get('role', ''),
'project_id': request.form.get('project_id', ''),
'weather': request.form.get('weather', ''),
'milestones': request.form.get('milestones', ''),
'reflection': request.form.get('reflection', '')
}
if action == 'generate':
# Validate all fields
if not all([form_data['supervisor_id'], form_data['role'], form_data['project_id'],
form_data['weather'], form_data['milestones'], form_data['reflection']]):
error = "Error: All fields are required."
else:
# First, try to fetch existing data from Salesforce
sf_data = fetch_salesforce_data(form_data['supervisor_id'], form_data['project_id'])
if sf_data:
output = sf_data
else:
# If no data exists, generate new output
data = {
'supervisor_id': form_data['supervisor_id'],
'role': form_data['role'],
'project_id': form_data['project_id'],
'milestones': [m.strip() for m in form_data['milestones'].split(',') if m.strip()],
'reflection_log': form_data['reflection'],
'weather': form_data['weather']
}
coaching_output = generate_coaching_output(data)
if coaching_output:
success = save_to_salesforce(coaching_output, data['supervisor_id'], data['project_id'])
if success:
output = coaching_output
else:
error = "Error: Failed to save to Salesforce."
else:
error = "Error: Failed to generate coaching output."
return render_template('index.html', form_data=form_data, output=output, error=error)
@app.route('/health', methods=['GET'])
def health_check():
"""
Health check endpoint.
"""
return jsonify({"status": "healthy", "message": "Application is running"}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)