lokesh341 commited on
Commit
b4c4230
·
verified ·
1 Parent(s): 2d909c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -221
app.py CHANGED
@@ -1,239 +1,161 @@
1
- import requests
 
 
 
 
 
 
 
2
  import json
3
  import os
4
- import logging
5
- from datetime import datetime
6
- from dotenv import load_dotenv
7
- from flask import Flask, jsonify, request, render_template, redirect, url_for, session
8
 
9
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
10
  logger = logging.getLogger(__name__)
11
 
12
- load_dotenv()
13
-
14
- HUGGING_FACE_API_URL = os.getenv("HUGGING_FACE_API_URL", "https://api-inference.huggingface.co/models/distilgpt2")
15
- HUGGING_FACE_API_TOKEN = os.getenv("HUGGING_FACE_API_TOKEN")
16
-
17
- if not HUGGING_FACE_API_TOKEN:
18
- logger.error("HUGGING_FACE_API_TOKEN is not set")
19
- raise ValueError("HUGGING_FACE_API_TOKEN environment variable is not set")
20
- if not HUGGING_FACE_API_URL.startswith("https://api-inference.huggingface.co/models/"):
21
- logger.error("Invalid HUGGING_FACE_API_URL: %s", HUGGING_FACE_API_URL)
22
- raise ValueError("HUGGING_FACE_API_URL must point to a valid Hugging Face model")
23
-
24
- app = Flask(__name__)
25
- app.secret_key = os.getenv("FLASK_SECRET_KEY", "your-secret-key")
26
-
27
- def generate_coaching_output(data):
28
- logger.info("Generating coaching output for supervisor %s", data['supervisor_id'])
29
- milestones_json = json.dumps(data['milestones'], indent=2)
30
- prompt = f"""
31
- 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.
32
 
33
- Supervisor Role: {data['role']}
34
- Project Milestones: {milestones_json}
35
- Reflection Log: {data['reflection_log']}
36
- Weather: {data['weather']}
37
-
38
- Format the response as JSON:
39
- {{
40
- "checklist": ["item1", "item2", ...],
41
- "tips": ["tip1", "tip2", "tip3"],
42
- "quote": "motivational quote"
43
- }}
44
- """
45
-
46
- headers = {
47
- "Authorization": f"Bearer {HUGGING_FACE_API_TOKEN}",
48
- "Content-Type": "application/json"
49
- }
50
- payload = {
51
- "inputs": prompt,
52
- "parameters": {
53
- "max_length": 200,
54
- "temperature": 0.7,
55
- "top_p": 0.9
56
- }
57
- }
58
 
 
 
59
  try:
60
- response = requests.post(HUGGING_FACE_API_URL, headers=headers, json=payload, timeout=5)
61
- response.raise_for_status()
62
- result = response.json()
63
- generated_text = result[0]["generated_text"] if isinstance(result, list) else result["generated_text"]
64
-
65
- start_idx = generated_text.find('{')
66
- end_idx = generated_text.rfind('}') + 1
67
- if start_idx == -1 or end_idx == 0:
68
- logger.error("No valid JSON found in LLM output")
69
- raise ValueError("No valid JSON found in LLM output")
70
-
71
- json_str = generated_text[start_idx:end_idx]
72
- output = json.loads(json_str)
73
- logger.info("Successfully generated coaching output")
74
- return output
75
-
76
- except requests.exceptions.HTTPError as e:
77
- logger.error("Hugging Face API HTTP error: %s", e)
78
- return None
79
- except (json.JSONDecodeError, ValueError) as e:
80
- logger.error("Error parsing LLM output: %s", e)
81
- return None
82
  except Exception as e:
83
- logger.error("Unexpected error in Hugging Face API call: %s", e)
84
- return None
85
-
86
- def save_to_salesforce(output, supervisor_id, project_id):
87
- logger.info("Mock saving to Salesforce for supervisor %s", supervisor_id)
88
- return True # Mocked success
89
-
90
- @app.route('/', methods=['GET'])
91
- def redirect_to_login():
92
- if 'user_id' in session or 'is_guest' in session:
93
- return redirect(url_for('ui'))
94
- return redirect(url_for('login_page'))
95
-
96
- @app.route('/login', methods=['GET'])
97
- def login_page():
98
- if 'user_id' in session or 'is_guest' in session:
99
- return redirect(url_for('ui'))
100
- return render_template('login.html')
101
-
102
- @app.route('/login', methods=['POST'])
103
- def login():
104
- data = request.get_json()
105
- username = data.get('username')
106
- password = data.get('password')
107
 
 
 
108
  try:
109
- # Mock Salesforce login
110
- if username == "testuser" and password == "testpass":
111
- supervisor_id = "MOCK_SUP_001"
112
- session['user_id'] = supervisor_id
113
- session['is_guest'] = False
114
- logger.info("Mock user %s logged in successfully", username)
115
- return jsonify({"status": "success", "message": "Logged in successfully"}), 200
 
 
 
 
 
 
 
 
116
  else:
117
- logger.error("Mock login failed for user %s: Invalid credentials", username)
118
- return jsonify({"status": "error", "message": "Invalid credentials"}), 401
119
-
120
  except Exception as e:
121
- logger.error("Error during mock login for user %s: %s", username, e)
122
- return jsonify({"status": "error", "message": str(e)}), 500
123
-
124
- @app.route('/signup', methods=['POST'])
125
- def signup():
126
- data = request.get_json()
127
- username = data.get('username')
128
- password = data.get('password')
129
- name = data.get('name', 'New Supervisor')
130
-
131
- try:
132
- # Mock Salesforce signup
133
- supervisor_id = f"MOCK_SUP_{username}_{datetime.now().strftime('%Y%m%d%H%M%S')}"
134
- session['user_id'] = supervisor_id
135
- session['is_guest'] = False
136
- logger.info("Mock user %s signed up successfully", username)
137
- return jsonify({"status": "success", "message": "Signed up successfully"}), 200
138
-
139
- except Exception as e:
140
- logger.error("Error during mock signup: %s", e)
141
- return jsonify({"status": "error", "message": str(e)}), 500
142
-
143
- @app.route('/guest_login', methods=['POST'])
144
- def guest_login():
145
- try:
146
- session['is_guest'] = True
147
- session['user_id'] = 'GUEST'
148
- logger.info("Guest login successful")
149
- return jsonify({"status": "success", "message": "Logged in as guest"}), 200
150
- except Exception as e:
151
- logger.error("Error during guest login: %s", e)
152
- return jsonify({"status": "error", "message": "Failed to log in as guest: " + str(e)}), 500
153
-
154
- @app.route('/logout', methods=['POST'])
155
- def logout():
 
 
 
 
 
 
 
 
 
 
 
 
156
  try:
157
- session.pop('user_id', None)
158
- session.pop('is_guest', None)
159
- logger.info("User logged out successfully")
160
- return jsonify({"status": "success", "message": "Logged out successfully"}), 200
161
- except Exception as e:
162
- logger.error("Error during logout: %s", e)
163
- return jsonify({"status": "error", "message": str(e)}), 500
164
-
165
- @app.route('/get_supervisor_data', methods=['GET'])
166
- def get_supervisor_data():
167
- user_id = session.get('user_id', 'GUEST')
168
- if user_id == 'GUEST':
169
- logger.info("Fetching default data for guest user")
170
- return jsonify({
171
- "status": "success",
172
- "data": {
173
- "supervisor_id": "GUEST",
174
- "role": "Guest",
175
- "project_id": "PRJ_GUEST",
176
- "location": "Unknown",
177
- "milestones": [],
178
- "reflection_log": "",
179
- "weather": "Unknown"
180
- }
181
- }), 200
182
-
183
- # Mock Salesforce data
184
- logger.info("Fetching mock Salesforce data for user %s", user_id)
185
- return jsonify({
186
- "status": "success",
187
- "data": {
188
- "supervisor_id": user_id,
189
- "role": "Site Supervisor",
190
- "project_id": "PRJ_DEFAULT",
191
- "location": "Construction Site A",
192
- "milestones": [
193
- {"task": "Foundation Work", "status": "In Progress"},
194
- {"task": "Framing", "status": "Not Started"}
195
- ],
196
- "reflection_log": "Mock reflection log",
197
- "weather": "Sunny, 25°C"
198
  }
199
- }), 200
200
-
201
- @app.route('/ui', methods=['GET'])
202
- def ui():
203
- if 'user_id' not in session and 'is_guest' not in session:
204
- logger.info("No session found, redirecting to login")
205
- return redirect(url_for('login_page'))
206
- logger.info("Rendering UI for user %s", session.get('user_id', 'GUEST'))
207
- return render_template('index.html')
208
-
209
- @app.route('/generate', methods=['POST'])
210
- def generate_endpoint():
211
- try:
212
- data = request.get_json()
213
- if not data or not all(key in data for key in ['supervisor_id', 'role', 'project_id', 'milestones', 'reflection_log', 'weather']):
214
- logger.error("Invalid or missing supervisor data in generate request")
215
- return jsonify({"status": "error", "message": "Invalid or missing supervisor data"}), 400
216
-
217
- coaching_output = generate_coaching_output(data)
218
- if coaching_output:
219
- success = save_to_salesforce(coaching_output, data["supervisor_id"], data["project_id"])
220
- if success:
221
- logger.info("Successfully generated and saved coaching output for %s", data["supervisor_id"])
222
- return jsonify({"status": "success", "output": coaching_output}), 200
223
- else:
224
- logger.error("Failed to save coaching output to Salesforce for %s", data["supervisor_id"])
225
- return jsonify({"status": "error", "message": "Failed to save to Salesforce"}), 500
226
- else:
227
- logger.error("Failed to generate coaching output for %s", data["supervisor_id"])
228
- return jsonify({"status": "error", "message": "Failed to generate coaching output"}), 500
229
  except Exception as e:
230
- logger.error("Error in generate endpoint: %s", e)
231
- return jsonify({"status": "error", "message": str(e)}), 500
232
-
233
- @app.route('/health', methods=['GET'])
234
- def health_check():
235
- logger.info("Health check requested")
236
- return jsonify({"status": "healthy", "message": "Application is running"}), 200
237
 
 
238
  if __name__ == "__main__":
239
- app.run(host="0.0.0.0", port=int(os.getenv("PORT", 7860)))
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from sklearn.ensemble import RandomForestRegressor
4
+ from sklearn.preprocessing import StandardScaler
5
+ from datetime import datetime, timedelta
6
+ import logging
7
+ from fastapi import FastAPI, HTTPException
8
+ import uvicorn
9
  import json
10
  import os
 
 
 
 
11
 
12
+ # Configure logging
13
+ logging.basicConfig(level=logging.INFO)
14
  logger = logging.getLogger(__name__)
15
 
16
+ # Check for Hugging Face API token
17
+ HF_API_TOKEN = os.getenv("HUGGING_FACE_API_TOKEN")
18
+ if not HF_API_TOKEN:
19
+ logger.warning("HUGGING_FACE_API_TOKEN not set. Some Hugging Face features may be unavailable.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ app = FastAPI()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ # Mock data loading function (replace with actual data source in production)
24
+ def load_data():
25
  try:
26
+ # Simulated data for project schedule, historical consumption, weather, etc.
27
+ data = {
28
+ 'date': [datetime.now().date() - timedelta(days=x) for x in range(30)],
29
+ 'project_id': ['PROJ001'] * 30,
30
+ 'task_type': ['Concrete_Pouring'] * 15 + ['Brick_Laying'] * 15,
31
+ 'cement_qty': np.random.uniform(100, 500, 30),
32
+ 'steel_qty': np.random.uniform(50, 200, 30),
33
+ 'brick_qty': np.random.uniform(1000, 5000, 30),
34
+ 'labor_headcount': np.random.randint(10, 50, 30),
35
+ 'temperature': np.random.uniform(15, 35, 30),
36
+ 'absenteeism_rate': np.random.uniform(0, 0.1, 30),
37
+ 'material_lead_time': np.random.uniform(1, 5, 30)
38
+ }
39
+ return pd.DataFrame(data)
 
 
 
 
 
 
 
 
40
  except Exception as e:
41
+ logger.error(f"Error loading data: {str(e)}")
42
+ raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ # Preprocess data for model input
45
+ def preprocess_data(df, is_training=True):
46
  try:
47
+ # Feature engineering
48
+ df['day_of_week'] = df['date'].apply(lambda x: x.weekday())
49
+ df['is_weekend'] = df['day_of_week'].apply(lambda x: 1 if x >= 5 else 0)
50
+
51
+ # Encode categorical variables
52
+ df = pd.get_dummies(df, columns=['task_type', 'project_id'])
53
+
54
+ # Define features and targets
55
+ features = [col for col in df.columns if col not in ['date', 'cement_qty', 'steel_qty', 'brick_qty', 'labor_headcount']]
56
+ targets = ['cement_qty', 'steel_qty', 'brick_qty', 'labor_headcount']
57
+
58
+ if is_training:
59
+ X = df[features]
60
+ y = df[targets]
61
+ return X, y
62
  else:
63
+ return df[features]
 
 
64
  except Exception as e:
65
+ logger.error(f"Error preprocessing data: {str(e)}")
66
+ raise
67
+
68
+ # Train or load model
69
+ class AIEstimator:
70
+ def __init__(self):
71
+ self.models = {}
72
+ self.scaler = StandardScaler()
73
+
74
+ def train(self, X, y):
75
+ try:
76
+ # Scale features
77
+ X_scaled = self.scaler.fit_transform(X)
78
+
79
+ # Train a RandomForestRegressor for each target
80
+ for target in y.columns:
81
+ model = RandomForestRegressor(n_estimators=100, random_state=42)
82
+ model.fit(X_scaled, y[target])
83
+ self.models[target] = model
84
+ logger.info(f"Trained model for {target}")
85
+ except Exception as e:
86
+ logger.error(f"Error training model: {str(e)}")
87
+ raise
88
+
89
+ def predict(self, X):
90
+ try:
91
+ # Scale features
92
+ X_scaled = self.scaler.transform(X)
93
+
94
+ # Predict for each target
95
+ predictions = {}
96
+ for target, model in self.models.items():
97
+ pred = model.predict(X_scaled)
98
+ predictions[target] = pred.tolist()
99
+
100
+ # Calculate forecast confidence (simplified as model score)
101
+ confidence = {target: model.score(X_scaled, pred) for target, model in self.models.items()}
102
+ predictions['forecast_confidence'] = confidence
103
+
104
+ return predictions
105
+ except Exception as e:
106
+ logger.error(f"Error making predictions: {str(e)}")
107
+ raise
108
+
109
+ # API endpoint for forecast generation
110
+ @app.post("/forecast")
111
+ async def generate_forecast(data: dict):
112
  try:
113
+ # Validate input
114
+ required_fields = ['project_id', 'date', 'task_type', 'temperature', 'absenteeism_rate', 'material_lead_time']
115
+ if not all(field in data for field in required_fields):
116
+ raise HTTPException(status_code=400, detail="Missing required fields")
117
+
118
+ # Convert input to DataFrame
119
+ input_df = pd.DataFrame([data])
120
+ input_df['date'] = pd.to_datetime(input_df['date']).dt.date
121
+
122
+ # Load historical data and append new input
123
+ historical_data = load_data()
124
+ combined_data = pd.concat([historical_data, input_df], ignore_index=True)
125
+
126
+ # Preprocess data
127
+ X = preprocess_data(combined_data, is_training=False)
128
+ X_new = X.tail(1) # Get features for the new input
129
+
130
+ # Load or train model
131
+ estimator = AIEstimator()
132
+ if not estimator.models:
133
+ X_train, y_train = preprocess_data(historical_data, is_training=True)
134
+ estimator.train(X_train, y_train)
135
+
136
+ # Generate forecast
137
+ forecast = estimator.predict(X_new)
138
+
139
+ # Format response
140
+ response = {
141
+ 'project_id': data['project_id'],
142
+ 'date': data['date'],
143
+ 'material_needed': {
144
+ 'cement_qty': forecast['cement_qty'][0],
145
+ 'steel_qty': forecast['steel_qty'][0],
146
+ 'brick_qty': forecast['brick_qty'][0]
147
+ },
148
+ 'labor_needed': forecast['labor_headcount'][0],
149
+ 'forecast_confidence': forecast['forecast_confidence'],
150
+ 'alert_flag': any(conf < 0.85 for conf in forecast['forecast_confidence'].values())
 
 
 
151
  }
152
+
153
+ logger.info(f"Forecast generated for project {data['project_id']}")
154
+ return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  except Exception as e:
156
+ logger.error(f"Error in forecast endpoint: {str(e)}")
157
+ raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
158
 
159
+ # Run the application (for local testing)
160
  if __name__ == "__main__":
161
+ uvicorn.run(app, host="0.0.0.0", port=8000)