|
from flask import Flask, request, jsonify, send_from_directory |
|
from flask_cors import CORS |
|
import joblib, numpy as np, json, math, xgboost as xgb, logging |
|
|
|
app = Flask(__name__, static_folder=".", static_url_path="") |
|
CORS(app) |
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
try: |
|
rf = joblib.load("rf_model.pkl") |
|
xgb_model = xgb.Booster() |
|
xgb_model.load_model("xgb_model.json") |
|
app.logger.info("β
Models loaded.") |
|
except Exception as e: |
|
app.logger.error(f"β Model load error: {e}") |
|
raise |
|
|
|
|
|
with open("tile_catalog.json") as f: |
|
tile_catalog = json.load(f) |
|
with open("tile_sizes.json") as f: |
|
tile_sizes = json.load(f) |
|
|
|
@app.route('/') |
|
def homepage(): |
|
return send_from_directory(".", "index.html") |
|
|
|
@app.route('/recommend', methods=['POST']) |
|
def recommend(): |
|
data = request.get_json() |
|
|
|
for key in ('tile_type','length','width','area','price_range'): |
|
if key not in data: |
|
return jsonify({"error":f"Missing {key}"}),400 |
|
|
|
length = float(data['length']); width = float(data['width']) |
|
coverage = length * width |
|
|
|
features = np.array([[0 if data['tile_type']=='floor' else 1, data['area'], coverage, *data['price_range'], data['price_range'][1]/coverage, coverage/data['price_range'][1]]]) |
|
xgb_pred = xgb_model.predict(xgb.DMatrix(features))[0] |
|
rf_pred = rf.predict_proba(features)[0,1] |
|
score = (xgb_pred+rf_pred)/2 |
|
|
|
|
|
recs = [] |
|
for p in tile_catalog: |
|
if p['type']==data['tile_type'] and p['size']==f"{length}x{width}" and data['price_range'][0] <= p['price'] <= data['price_range'][1]: |
|
recs.append({**p}) |
|
return jsonify({"recommendation_score": round(score,3), "recommended_products": recs}) |
|
|
|
if __name__=="__main__": |
|
app.run(host="0.0.0.0", port=7860, debug=False) |
|
|