Update app.py
Browse files
app.py
CHANGED
@@ -10,11 +10,9 @@ import logging
|
|
10 |
|
11 |
app = Flask(__name__, static_folder=".", static_url_path="")
|
12 |
CORS(app)
|
13 |
-
|
14 |
-
# Setup logging
|
15 |
logging.basicConfig(level=logging.INFO)
|
16 |
|
17 |
-
# Load models
|
18 |
try:
|
19 |
rf = joblib.load("rf_model.pkl")
|
20 |
xgb_model = xgb.Booster()
|
@@ -24,19 +22,23 @@ except Exception as e:
|
|
24 |
app.logger.error(f"❌ Error loading models: {e}")
|
25 |
raise e
|
26 |
|
27 |
-
# Load
|
28 |
with open("tile_catalog.json", "r", encoding="utf-8") as f:
|
29 |
tile_catalog = json.load(f)
|
30 |
|
31 |
with open("tile_sizes.json", "r", encoding="utf-8") as f:
|
32 |
tile_sizes = json.load(f)
|
33 |
|
34 |
-
# Serve
|
35 |
@app.route('/')
|
36 |
def serve_index():
|
37 |
return send_from_directory('.', 'index.html')
|
38 |
|
39 |
-
|
|
|
|
|
|
|
|
|
40 |
@app.route('/recommend', methods=['POST'])
|
41 |
def recommend():
|
42 |
try:
|
@@ -82,7 +84,7 @@ def recommend():
|
|
82 |
app.logger.error(f"Error in /recommend: {str(e)}")
|
83 |
return jsonify({"error": "Internal server error"}), 500
|
84 |
|
85 |
-
# ===
|
86 |
@app.route('/calculate', methods=['POST'])
|
87 |
def calculate():
|
88 |
try:
|
@@ -100,10 +102,8 @@ def calculate():
|
|
100 |
validate_positive_number(data['area'], "area")
|
101 |
|
102 |
tile_info = tile_sizes[data['tile_size']]
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
tiles_needed = math.ceil((data['area'] / area_per_tile_ft2) * 1.1)
|
107 |
tiles_per_box = tile_info.get('tiles_per_box', 10)
|
108 |
boxes_needed = math.ceil(tiles_needed / tiles_per_box)
|
109 |
|
@@ -126,7 +126,7 @@ def calculate():
|
|
126 |
app.logger.error(f"Error in /calculate: {str(e)}")
|
127 |
return jsonify({"error": "Internal server error"}), 500
|
128 |
|
129 |
-
# ===
|
130 |
|
131 |
def prepare_features(data):
|
132 |
tile_type_num = 0 if data['tile_type'] == 'floor' else 1
|
|
|
10 |
|
11 |
app = Flask(__name__, static_folder=".", static_url_path="")
|
12 |
CORS(app)
|
|
|
|
|
13 |
logging.basicConfig(level=logging.INFO)
|
14 |
|
15 |
+
# === Load models ===
|
16 |
try:
|
17 |
rf = joblib.load("rf_model.pkl")
|
18 |
xgb_model = xgb.Booster()
|
|
|
22 |
app.logger.error(f"❌ Error loading models: {e}")
|
23 |
raise e
|
24 |
|
25 |
+
# === Load data ===
|
26 |
with open("tile_catalog.json", "r", encoding="utf-8") as f:
|
27 |
tile_catalog = json.load(f)
|
28 |
|
29 |
with open("tile_sizes.json", "r", encoding="utf-8") as f:
|
30 |
tile_sizes = json.load(f)
|
31 |
|
32 |
+
# === Serve Frontend ===
|
33 |
@app.route('/')
|
34 |
def serve_index():
|
35 |
return send_from_directory('.', 'index.html')
|
36 |
|
37 |
+
@app.route('/<path:path>')
|
38 |
+
def serve_static(path):
|
39 |
+
return send_from_directory('.', path)
|
40 |
+
|
41 |
+
# === Recommend Endpoint ===
|
42 |
@app.route('/recommend', methods=['POST'])
|
43 |
def recommend():
|
44 |
try:
|
|
|
84 |
app.logger.error(f"Error in /recommend: {str(e)}")
|
85 |
return jsonify({"error": "Internal server error"}), 500
|
86 |
|
87 |
+
# === Calculate Endpoint ===
|
88 |
@app.route('/calculate', methods=['POST'])
|
89 |
def calculate():
|
90 |
try:
|
|
|
102 |
validate_positive_number(data['area'], "area")
|
103 |
|
104 |
tile_info = tile_sizes[data['tile_size']]
|
105 |
+
area_per_tile = tile_info['length'] * tile_info['width']
|
106 |
+
tiles_needed = math.ceil((data['area'] / area_per_tile) * 1.1)
|
|
|
|
|
107 |
tiles_per_box = tile_info.get('tiles_per_box', 10)
|
108 |
boxes_needed = math.ceil(tiles_needed / tiles_per_box)
|
109 |
|
|
|
126 |
app.logger.error(f"Error in /calculate: {str(e)}")
|
127 |
return jsonify({"error": "Internal server error"}), 500
|
128 |
|
129 |
+
# === Utils ===
|
130 |
|
131 |
def prepare_features(data):
|
132 |
tile_type_num = 0 if data['tile_type'] == 'floor' else 1
|