AjaykumarPilla commited on
Commit
686d487
·
verified ·
1 Parent(s): d00a16c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +191 -159
app.py CHANGED
@@ -1,160 +1,192 @@
1
  import gradio as gr
2
- import pandas as pd
3
- from fastapi import FastAPI, Request
4
- from fastapi.responses import JSONResponse
5
- import uvicorn
6
- from sklearn.linear_model import LinearRegression
7
- from sklearn.model_selection import train_test_split
8
- import os
9
- import uuid
10
- from datetime import datetime
11
- from fastapi.staticfiles import StaticFiles
12
- from reportlab.lib.pagesizes import A4
13
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
14
- from reportlab.lib.styles import getSampleStyleSheet
15
-
16
- # Hardcoded mappings
17
- weather_map = {"Cloudy": 0, "Rainy": 1, "Sunny": 2}
18
-
19
- # Load and preprocess training data
20
- df = pd.read_csv("new_delay_data.csv")
21
-
22
- # Encode categorical features
23
- df = pd.get_dummies(df, columns=["Phase"], drop_first=True) # Finishing as baseline
24
- df["Weather"] = df["Weather"].map(weather_map)
25
-
26
- # Handle missing or invalid mappings
27
- df.dropna(subset=["Phase_Framing", "Phase_Foundation", "Weather", "Absentee", "DelayLog", "Delay%"], inplace=True)
28
-
29
- # Split features and target
30
- X = df[["Phase_Framing", "Phase_Foundation", "Weather", "Absentee", "DelayLog"]]
31
- y = df["Delay%"]
32
-
33
- # Train model
34
- model = LinearRegression()
35
- model.fit(X, y)
36
-
37
- # Function to clean up old files
38
- def clean_tmp():
39
- directory = "./static_files"
40
- for file in os.listdir(directory):
41
- if file.endswith(".pdf"):
42
- try:
43
- os.remove(os.path.join(directory, file))
44
- except OSError:
45
- pass
46
-
47
- # Function to generate PDF using reportlab
48
- def generate_pdf(phase, weather, absentee_pct, delay_log, prediction, risk, insight):
49
- os.makedirs("./static_files", exist_ok=True)
50
- clean_tmp()
51
- pdf_filename = f"delay_report_{uuid.uuid4().hex}.pdf"
52
- pdf_path = f"./static_files/{pdf_filename}"
53
-
54
- doc = SimpleDocTemplate(pdf_path, pagesize=A4)
55
- styles = getSampleStyleSheet()
56
- story = []
57
-
58
- story.append(Paragraph("Delay Prediction Report", styles['Title']))
59
- story.append(Spacer(1, 12))
60
- story.append(Paragraph(f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", styles['Normal']))
61
- story.append(Spacer(1, 12))
62
-
63
- story.append(Paragraph("Project Details", styles['Heading2']))
64
- story.append(Paragraph(f"Phase: {phase}", styles['Normal']))
65
- story.append(Paragraph(f"Weather: {weather}", styles['Normal']))
66
- story.append(Paragraph(f"Absentee %: {absentee_pct:.2f}%", styles['Normal']))
67
- story.append(Paragraph(f"Previous Delay Log: {delay_log:.2f} days", styles['Normal']))
68
- story.append(Spacer(1, 12))
69
-
70
- story.append(Paragraph("Prediction Results", styles['Heading2']))
71
- story.append(Paragraph(f"Predicted Delay: {prediction:.2f}%", styles['Normal']))
72
- story.append(Paragraph(f"Risk Level: {risk}", styles['Normal']))
73
- story.append(Paragraph(f"AI Insight: {insight}", styles['Normal']))
74
-
75
- doc.build(story)
76
-
77
- pdf_url = f"https://ajaykumarpilla-delay-predictor.hf.space/static/{pdf_filename}"
78
- return pdf_url, pdf_path
79
-
80
- # Main prediction function
81
- def predict_delay(phase, weather, absentee_pct, delay_log):
82
- framing = 1 if phase == "Framing" else 0
83
- foundation = 1 if phase == "Foundation" else 0
84
- weather_encoded = weather_map.get(weather, 0)
85
- input_data = [[framing, foundation, weather_encoded, absentee_pct, delay_log]]
86
-
87
- prediction = model.predict(input_data)[0]
88
- prediction = round(prediction, 2)
89
-
90
- if prediction >= 75:
91
- risk = "High Risk"
92
- elif prediction >= 50:
93
- risk = "Moderate Risk"
94
- else:
95
- risk = "Low Risk"
96
-
97
- insight = f"Phase: {phase}, Weather: {weather}, Absenteeism: {absentee_pct}%, Previous Delay: {delay_log} → Risk: {risk}"
98
-
99
- pdf_url, pdf_path = generate_pdf(phase, weather, absentee_pct, delay_log, prediction, risk, insight)
100
- return prediction, risk, insight, pdf_url
101
-
102
- # FastAPI for Salesforce
103
- api_app = FastAPI()
104
- os.makedirs("./static_files", exist_ok=True)
105
- api_app.mount("/static", StaticFiles(directory="./static_files"), name="static")
106
-
107
- @api_app.post("/predict")
108
- async def predict_from_salesforce(request: Request):
109
- try:
110
- data = await request.json()
111
- phase = data.get("phase", "Framing")
112
- weather = data.get("weather", "Sunny")
113
- absentee_pct = float(data.get("absentee_pct", 0))
114
- delay_log = float(data.get("delay_log", 0))
115
-
116
- prediction, risk, insight, pdf_url = predict_delay(phase, weather, absentee_pct, delay_log)
117
-
118
- return JSONResponse(content={
119
- "delay_probability": prediction,
120
- "risk_alert": risk,
121
- "ai_insight": insight,
122
- "pdf_url": pdf_url,
123
- "status": "success"
124
- })
125
- except Exception as e:
126
- return JSONResponse(status_code=500, content={"status": "error", "message": str(e)})
127
-
128
- # Gradio UI for manual testing
129
- with gr.Blocks() as demo:
130
- gr.Markdown("## 🏗️ Delay Predictor")
131
- with gr.Row():
132
- phase_input = gr.Textbox(label="Phase (Framing/Foundation/Finishing)")
133
- weather_input = gr.Textbox(label="Weather (Sunny/Rainy/Cloudy)")
134
- with gr.Row():
135
- absentee_input = gr.Number(label="Absentee %")
136
- delay_input = gr.Number(label="Previous Delay Log")
137
- output = gr.Textbox(label="Prediction Summary")
138
- pdf_output = gr.File(label="Download PDF Report")
139
-
140
- def predict_and_format(phase, weather, absentee, delay_log):
141
- try:
142
- prediction, risk, insight, pdf_url = predict_delay(phase, weather, absentee, delay_log)
143
- return (
144
- f"Predicted Delay: {prediction}%\nRisk Level: {risk}\nInsight: {insight}\nPDF URL: {pdf_url}",
145
- pdf_url
146
- )
147
- except Exception as e:
148
- return f"Error: {str(e)}", None
149
-
150
- submit = gr.Button("Predict")
151
- submit.click(
152
- predict_and_format,
153
- inputs=[phase_input, weather_input, absentee_input, delay_input],
154
- outputs=[output, pdf_output]
155
- )
156
-
157
- app = gr.mount_gradio_app(api_app, demo, path="/")
158
-
159
- if __name__ == "__main__":
160
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import pandas as pd
3
+ from fastapi import FastAPI, Request
4
+ from fastapi.responses import JSONResponse
5
+ import uvicorn
6
+ from sklearn.linear_model import LinearRegression
7
+ from sklearn.model_selection import train_test_split
8
+ import os
9
+ import subprocess
10
+ import uuid
11
+ from datetime import datetime
12
+ from fastapi.staticfiles import StaticFiles
13
+
14
+ # Hardcoded mappings
15
+ weather_map = {"Cloudy": 0, "Rainy": 1, "Sunny": 2}
16
+
17
+ # Load and preprocess training data
18
+ df = pd.read_csv("new_delay_data.csv")
19
+
20
+ # Encode categorical features
21
+ df = pd.get_dummies(df, columns=["Phase"], drop_first=True) # Finishing as baseline
22
+ df["Weather"] = df["Weather"].map(weather_map)
23
+
24
+ # Handle missing or invalid mappings
25
+ df.dropna(subset=["Phase_Framing", "Phase_Foundation", "Weather", "Absentee", "DelayLog", "Delay%"], inplace=True)
26
+
27
+ # Split features and target
28
+ X = df[["Phase_Framing", "Phase_Foundation", "Weather", "Absentee", "DelayLog"]]
29
+ y = df["Delay%"]
30
+
31
+ # Train model
32
+ model = LinearRegression()
33
+ model.fit(X, y)
34
+
35
+ # Function to clean up old files
36
+ def clean_tmp():
37
+ directory = "./static_files"
38
+ for file in os.listdir(directory):
39
+ if file.endswith((".pdf", ".tex", ".aux", ".log")):
40
+ try:
41
+ os.remove(os.path.join(directory, file))
42
+ except OSError:
43
+ pass
44
+
45
+ # Function to generate LaTeX content for PDF
46
+ def generate_latex_content(phase, weather, absentee_pct, delay_log, prediction, risk, insight):
47
+ return f"""
48
+ \\documentclass[a4paper,12pt]{{article}}
49
+ \\usepackage{{geometry}}
50
+ \\usepackage{{utf8x}}
51
+ \\usepackage{{parskip}}
52
+ \\usepackage{{titlesec}}
53
+ \\usepackage{{xcolor}}
54
+ \\geometry{{margin=1in}}
55
+ \\titleformat{{\\section}}{{\\Large\\bfseries\\color{{blue}}}}{{\\thesection}}{{1em}}{{}}
56
+ \\begin{{document}}
57
+ \\section*{{Delay Prediction Report}}
58
+ \\textbf{{Generated on:}} {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\\\
59
+ \\textbf{{Project Details}}\\\\
60
+ \\begin{{itemize}}
61
+ \\item \\textbf{{Phase:}} {phase}
62
+ \\item \\textbf{{Weather:}} {weather}
63
+ \\item \\textbf{{Absentee \\%:}} {absentee_pct:.2f}\\%
64
+ \\item \\textbf{{Previous Delay Log:}} {delay_log:.2f} days
65
+ \\end{{itemize}}
66
+ \\vspace{{0.5cm}}
67
+ \\textbf{{Prediction Results}}\\\\
68
+ \\begin{{itemize}}
69
+ \\item \\textbf{{Predicted Delay:}} {prediction:.2f}\\%
70
+ \\item \\textbf{{Risk Level:}} {risk}
71
+ \\item \\textbf{{AI Insight:}} {insight}
72
+ \\end{{itemize}}
73
+ \\end{{document}}
74
+ """
75
+
76
+ # Function to generate PDF and return its URL
77
+ def generate_pdf(phase, weather, absentee_pct, delay_log, prediction, risk, insight):
78
+ os.makedirs("./static_files", exist_ok=True)
79
+ clean_tmp() # Clean up old files
80
+ pdf_filename = f"delay_report_{uuid.uuid4().hex}.pdf"
81
+ tex_filename = f"./static_files/{pdf_filename.replace('.pdf', '.tex')}"
82
+ pdf_path = f"./static_files/{pdf_filename}"
83
+
84
+ latex_content = generate_latex_content(phase, weather, absentee_pct, delay_log, prediction, risk, insight)
85
+ with open(tex_filename, "w") as f:
86
+ f.write(latex_content)
87
+
88
+ try:
89
+ subprocess.run(
90
+ ["pdflatex", f"-output-directory=./static_files", tex_filename],
91
+ check=True,
92
+ stdout=subprocess.PIPE,
93
+ stderr=subprocess.PIPE,
94
+ text=True
95
+ )
96
+ except subprocess.CalledProcessError as e:
97
+ raise Exception(f"PDF generation failed: {e.stderr}")
98
+
99
+ for ext in [".aux", ".log", ".tex"]:
100
+ try:
101
+ os.remove(tex_filename.replace(".tex", ext))
102
+ except OSError:
103
+ pass
104
+
105
+ pdf_url = f"https://ajaykumarpilla-delay-predictor.hf.space/static/{pdf_filename}"
106
+ return pdf_url, pdf_path
107
+
108
+ # Main prediction function
109
+ def predict_delay(phase, weather, absentee_pct, delay_log):
110
+ framing = 1 if phase == "Framing" else 0
111
+ foundation = 1 if phase == "Foundation" else 0
112
+ weather_encoded = weather_map.get(weather, 0)
113
+ input_data = [[framing, foundation, weather_encoded, absentee_pct, delay_log]]
114
+
115
+ prediction = model.predict(input_data)[0]
116
+ prediction = round(prediction, 2)
117
+
118
+ if prediction >= 75:
119
+ risk = "High Risk"
120
+ elif prediction >= 50:
121
+ risk = "Moderate Risk"
122
+ else:
123
+ risk = "Low Risk"
124
+
125
+ insight = f"Phase: {phase}, Weather: {weather}, Absenteeism: {absentee_pct}%, Previous Delay: {delay_log} → Risk: {risk}"
126
+
127
+ pdf_url, pdf_path = generate_pdf(phase, weather, absentee_pct, delay_log, prediction, risk, insight)
128
+ return prediction, risk, insight, pdf_url
129
+
130
+ # FastAPI for Salesforce
131
+ api_app = FastAPI()
132
+
133
+ # Create static_files directory at startup
134
+ os.makedirs("./static_files", exist_ok=True)
135
+
136
+ # Mount static files directory
137
+ api_app.mount("/static", StaticFiles(directory="./static_files"), name="static")
138
+
139
+ @api_app.post("/predict")
140
+ async def predict_from_salesforce(request: Request):
141
+ try:
142
+ data = await request.json()
143
+ phase = data.get("phase", "Framing")
144
+ weather = data.get("weather", "Sunny")
145
+ absentee_pct = float(data.get("absentee_pct", 0))
146
+ delay_log = float(data.get("delay_log", 0))
147
+
148
+ prediction, risk, insight, pdf_url = predict_delay(phase, weather, absentee_pct, delay_log)
149
+
150
+ return JSONResponse(content={
151
+ "delay_probability": prediction,
152
+ "risk_alert": risk,
153
+ "ai_insight": insight,
154
+ "pdf_url": pdf_url,
155
+ "status": "success"
156
+ })
157
+ except Exception as e:
158
+ return JSONResponse(status_code=500, content={"status": "error", "message": str(e)})
159
+
160
+ # Gradio UI for manual testing
161
+ with gr.Blocks() as demo:
162
+ gr.Markdown("## �(:construction:) Delay Predictor")
163
+ with gr.Row():
164
+ phase_input = gr.Textbox(label="Phase (Framing/Foundation/Finishing)")
165
+ weather_input = gr.Textbox(label="Weather (Sunny/Rainy/Cloudy)")
166
+ with gr.Row():
167
+ absentee_input = gr.Number(label="Absentee %")
168
+ delay_input = gr.Number(label="Previous Delay Log")
169
+ output = gr.Textbox(label="Prediction Summary")
170
+ pdf_output = gr.File(label="Download PDF Report")
171
+
172
+ def predict_and_format(phase, weather, absentee, delay_log):
173
+ try:
174
+ prediction, risk, insight, pdf_url = predict_delay(phase, weather, absentee, delay_log)
175
+ return (
176
+ f"Predicted Delay: {prediction}%\nRisk Level: {risk}\nInsight: {insight}\nPDF URL: {pdf_url}",
177
+ pdf_url
178
+ )
179
+ except Exception as e:
180
+ return f"Error: {str(e)}", None
181
+
182
+ submit = gr.Button("Predict")
183
+ submit.click(
184
+ predict_and_format,
185
+ inputs=[phase_input, weather_input, absentee_input, delay_input],
186
+ outputs=[output, pdf_output]
187
+ )
188
+
189
+ app = gr.mount_gradio_app(api_app, demo, path="/")
190
+
191
+ if __name__ == "__main__":
192
+ uvicorn.run(app, host="0.0.0.0", port=7860)