lokesh341 commited on
Commit
0f7904a
·
verified ·
1 Parent(s): d413db2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -71
app.py CHANGED
@@ -1,83 +1,116 @@
1
- from flask import Flask, render_template, request, jsonify
2
- import requests
3
- import json
4
- from datetime import datetime
5
- import pandas as pd
 
 
 
 
6
 
7
- app = Flask(__name__)
 
8
 
9
- # Hugging Face API configuration
10
- HF_API_URL = "https://api-inference.huggingface.co/models/your-model-endpoint"
11
- HF_TOKEN = "your_hugging_face_token"
12
 
13
- # Simulated project task logs (replace with actual data source, e.g., Salesforce or database)
14
- def get_task_logs():
15
- return [
16
- {
17
- "project_id": "P001",
18
- "task_type": "Concrete",
19
- "weather_temp": 25.5,
20
- "absenteeism_rate": 0.1,
21
- "labour_count": 20
22
- },
23
- {
24
- "project_id": "P002",
25
- "task_type": "Masonry",
26
- "weather_temp": 22.0,
27
- "absenteeism_rate": 0.05,
28
- "labour_count": 15
29
- }
30
- ]
31
 
32
- # Call Hugging Face API for forecasting
33
- def call_hf_api(task_log):
34
- headers = {"Authorization": f"Bearer {HF_TOKEN}"}
35
- payload = {
36
- "project_id": task_log["project_id"],
37
- "task_type": task_log["task_type"],
38
- "weather_temp": task_log["weather_temp"],
39
- "absenteeism_rate": task_log["absenteeism_rate"],
40
- "labour_count": task_log["labour_count"],
41
- "date": datetime.now().strftime("%Y-%m-%d")
42
- }
43
- try:
44
- response = requests.post(HF_API_URL, headers=headers, json=payload, timeout=10)
45
- response.raise_for_status()
46
- return response.json()
47
- except requests.RequestException as e:
48
- return {"error": str(e), "project_id": task_log["project_id"]}
 
 
 
 
 
 
 
 
 
49
 
50
- # Generate placeholder PDF link (replace with actual PDF generation logic)
51
- def generate_pdf_link(forecast):
52
- return f"https://example.com/pdf/{forecast['project_id']}_{forecast['date']}.pdf"
53
 
54
- # Route for the dashboard
55
- @app.route("/")
56
- def dashboard():
57
- task_logs = get_task_logs()
58
- forecasts = []
 
 
 
 
59
 
60
- for log in task_logs:
61
- forecast = call_hf_api(log)
62
- if "error" not in forecast:
63
- forecast["pdf_link"] = generate_pdf_link(forecast)
64
- forecasts.append(forecast)
 
 
 
 
65
 
66
- return render_template("index.html", forecasts=forecasts)
67
-
68
- # Route for API access (optional, for external integrations)
69
- @app.route("/forecast", methods=["POST"])
70
- def forecast():
71
- data = request.json
72
- if not data:
73
- return jsonify({"error": "No input data provided"}), 400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- forecast = call_hf_api(data)
76
- if "error" in forecast:
77
- return jsonify({"error": forecast["error"]}), 500
 
78
 
79
- forecast["pdf_link"] = generate_pdf_link(forecast)
80
- return jsonify(forecast)
 
 
 
 
 
 
 
81
 
82
  if __name__ == "__main__":
83
- app.run(debug=True, host="0.0.0.0", port=5000)
 
1
+ from fastapi import FastAPI, HTTPException, Depends, Security
2
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
3
+ from pydantic import BaseModel
4
+ import numpy as np
5
+ from sklearn.linear_model import LinearRegression
6
+ import uvicorn
7
+ import os
8
+ from typing import List, Dict
9
+ import time
10
 
11
+ app = FastAPI(title="AI Estimator API")
12
+ security = HTTPBearer()
13
 
14
+ # Mock token for authentication (replace with Hugging Face Space secrets or env variable)
15
+ API_TOKEN = os.getenv("API_TOKEN", "hf_mock_token_123")
 
16
 
17
+ # Pydantic models for request/response
18
+ class TaskInput(BaseModel):
19
+ project_id: str
20
+ date: str
21
+ task_type: str
22
+ historical_consumption: Dict[str, float] # e.g., {"cement": 100, "steel": 50}
23
+ weather: Dict[str, float] # e.g., {"temperature": 25, "rain_probability": 0.1}
24
+ absenteeism_rate: float
25
+ material_lead_time: Dict[str, float] # e.g., {"cement": 2, "steel": 3}
 
 
 
 
 
 
 
 
 
26
 
27
+ class ForecastOutput(BaseModel):
28
+ project_id: str
29
+ date: str
30
+ task_type: str
31
+ material_needed: Dict[str, float]
32
+ labour_needed: Dict[str, float]
33
+ forecast_confidence: float
34
+ alert_flag: bool
35
+
36
+ # Mock trained model (replace with actual trained model in production)
37
+ class MockAIModel:
38
+ def __init__(self):
39
+ # Dummy coefficients for regression
40
+ self.material_model = LinearRegression()
41
+ self.labour_model = LinearRegression()
42
+ # Mock training (replace with actual training data)
43
+ X = np.array([[1, 25, 0.1, 0.05, 2], [2, 30, 0.2, 0.1, 1]]) # Features: task_type_id, temp, rain, absenteeism, lead_time
44
+ y_material = np.array([[100, 50], [120, 60]]) # cement, steel
45
+ y_labour = np.array([[10, 5], [12, 6]]) # trade1, trade2
46
+ self.material_model.fit(X, y_material)
47
+ self.labour_model.fit(X, y_labour)
48
+
49
+ def predict(self, features: np.ndarray):
50
+ material_pred = self.material_model.predict(features)[0]
51
+ labour_pred = self.labour_model.predict(features)[0]
52
+ return material_pred, labour_pred
53
 
54
+ # Initialize model
55
+ ai_model = MockAIModel()
 
56
 
57
+ # Token authentication
58
+ async def verify_token(credentials: HTTPAuthorizationCredentials = Security(security)):
59
+ if credentials.credentials != API_TOKEN:
60
+ raise HTTPException(status_code=401, detail="Invalid or missing API token")
61
+ return credentials.credentials
62
+
63
+ @app.post("/forecast", response_model=ForecastOutput, dependencies=[Depends(verify_token)])
64
+ async def generate_forecast(task: TaskInput):
65
+ start_time = time.time()
66
 
67
+ # Extract features for model
68
+ task_type_id = hash(task.task_type) % 100 # Mock task type encoding
69
+ features = np.array([[
70
+ task_type_id,
71
+ task.weather.get("temperature", 20),
72
+ task.weather.get("rain_probability", 0),
73
+ task.absenteeism_rate,
74
+ list(task.material_lead_time.values())[0] # Use first material lead time
75
+ ]])
76
 
77
+ # Generate predictions
78
+ material_pred, labour_pred = ai_model.predict(features)
79
+
80
+ # Format predictions
81
+ material_needed = {
82
+ "cement": max(0, material_pred[0]),
83
+ "steel": max(0, material_pred[1]),
84
+ "brick": max(0, material_pred[0] * 2) # Mock derived material
85
+ }
86
+ labour_needed = {
87
+ "carpenter": max(0, labour_pred[0]),
88
+ "mason": max(0, labour_pred[1]),
89
+ "laborer": max(0, labour_pred[0] + labour_pred[1]) # Mock derived trade
90
+ }
91
+
92
+ # Calculate confidence (mock: based on input completeness)
93
+ confidence = 0.85 if all([task.historical_consumption, task.weather, task.material_lead_time]) else 0.75
94
+
95
+ # Alert if resource gap exceeds 15% (mock comparison with historical)
96
+ historical_total = sum(task.historical_consumption.values())
97
+ predicted_total = sum(material_needed.values())
98
+ alert_flag = abs(predicted_total - historical_total) / historical_total > 0.15 if historical_total > 0 else False
99
 
100
+ # Ensure latency < 10s
101
+ elapsed_time = time.time() - start_time
102
+ if elapsed_time > 10:
103
+ raise HTTPException(status_code=500, detail="Forecast generation exceeded 10s")
104
 
105
+ return ForecastOutput(
106
+ project_id=task.project_id,
107
+ date=task.date,
108
+ task_type=task.task_type,
109
+ material_needed=material_needed,
110
+ labour_needed=labour_needed,
111
+ forecast_confidence=confidence,
112
+ alert_flag=alert_flag
113
+ )
114
 
115
  if __name__ == "__main__":
116
+ uvicorn.run(app, host="0.0.0.0", port=8000)