Spaces:
Running
Running
Upload app.py
Browse files- static/app.py +97 -0
static/app.py
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import pickle
|
3 |
+
import joblib
|
4 |
+
import numpy as np
|
5 |
+
import uvicorn
|
6 |
+
from fastapi import FastAPI, UploadFile, File
|
7 |
+
from fastapi.middleware.cors import CORSMiddleware
|
8 |
+
from fastapi.staticfiles import StaticFiles
|
9 |
+
from fastapi.responses import FileResponse
|
10 |
+
from extract import extract_features # Import feature extractor
|
11 |
+
|
12 |
+
# Initialize FastAPI app
|
13 |
+
app = FastAPI()
|
14 |
+
|
15 |
+
# Enable CORS
|
16 |
+
app.add_middleware(
|
17 |
+
CORSMiddleware,
|
18 |
+
allow_origins=["*"],
|
19 |
+
allow_credentials=True,
|
20 |
+
allow_methods=["*"],
|
21 |
+
allow_headers=["*"],
|
22 |
+
)
|
23 |
+
|
24 |
+
# Set up static files directory for frontend
|
25 |
+
app.mount("/static", StaticFiles(directory="static"), name="static")
|
26 |
+
|
27 |
+
# Load trained model, scaler, and feature list
|
28 |
+
model_path = "models/gender_model_lr.pkl"
|
29 |
+
scaler_path = "models/scaler_gender_model_lr.pkl"
|
30 |
+
feature_list_path = "models/feature_list.pkl"
|
31 |
+
|
32 |
+
model = joblib.load(model_path)
|
33 |
+
scaler = joblib.load(scaler_path)
|
34 |
+
with open(feature_list_path, "rb") as f:
|
35 |
+
feature_list = pickle.load(f)
|
36 |
+
|
37 |
+
print("β
Model, Scaler, and Feature List Loaded Successfully!")
|
38 |
+
|
39 |
+
|
40 |
+
# Route to serve UI (index.html)
|
41 |
+
@app.get("/")
|
42 |
+
async def serve_ui():
|
43 |
+
return FileResponse("static/index.html")
|
44 |
+
|
45 |
+
|
46 |
+
# Prediction API
|
47 |
+
@app.post("/predict")
|
48 |
+
async def predict(audio: UploadFile = File(...)):
|
49 |
+
try:
|
50 |
+
# Save uploaded file
|
51 |
+
UPLOAD_FOLDER = "uploads"
|
52 |
+
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
53 |
+
filepath = os.path.join(UPLOAD_FOLDER, audio.filename)
|
54 |
+
|
55 |
+
with open(filepath, "wb") as f:
|
56 |
+
f.write(await audio.read())
|
57 |
+
|
58 |
+
print(f"π’ Processing file: {audio.filename}")
|
59 |
+
|
60 |
+
# Extract features
|
61 |
+
features = extract_features(filepath)
|
62 |
+
if features is None:
|
63 |
+
return {"error": "Feature extraction failed"}
|
64 |
+
|
65 |
+
print(f"π’ Extracted {len(features)} features.")
|
66 |
+
|
67 |
+
# Scale features
|
68 |
+
features_scaled = scaler.transform([features])
|
69 |
+
print("π’ Features scaled successfully.")
|
70 |
+
|
71 |
+
# Predict gender
|
72 |
+
prediction = model.predict(features_scaled)[0]
|
73 |
+
confidence = model.predict_proba(features_scaled)[0]
|
74 |
+
print("π’ Prediction completed.")
|
75 |
+
|
76 |
+
# Format response
|
77 |
+
result = {
|
78 |
+
"gender": "Female" if prediction == 1 else "Male",
|
79 |
+
"confidence": float(max(confidence)),
|
80 |
+
"age_group": "Unknown"
|
81 |
+
}
|
82 |
+
|
83 |
+
print(f"β
Result: {result}")
|
84 |
+
|
85 |
+
# Delete temp file
|
86 |
+
os.remove(filepath)
|
87 |
+
|
88 |
+
return result
|
89 |
+
|
90 |
+
except Exception as e:
|
91 |
+
print(f"β Error: {e}")
|
92 |
+
return {"error": str(e)}
|
93 |
+
|
94 |
+
|
95 |
+
# Run FastAPI with Uvicorn
|
96 |
+
if __name__ == "__main__":
|
97 |
+
uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=True)
|