Spaces:
Runtime error
Runtime error
Update routes/recommend.py
Browse files- routes/recommend.py +11 -18
routes/recommend.py
CHANGED
|
@@ -226,32 +226,25 @@ def recommend_movie():
|
|
| 226 |
def recommend_book():
|
| 227 |
try:
|
| 228 |
data = request.get_json()
|
| 229 |
-
|
| 230 |
if not data:
|
| 231 |
return jsonify({"error": "No data provided"}), 400
|
| 232 |
-
|
| 233 |
rec_type = data.get('type')
|
| 234 |
genre = data.get('genre')
|
| 235 |
top_k = data.get('top_k', 10)
|
| 236 |
-
|
| 237 |
if not rec_type or not genre:
|
| 238 |
return jsonify({"error": "Missing 'type' or 'genre'"}), 400
|
| 239 |
-
|
| 240 |
if rec_type not in RECOMMENDER_ENDPOINTS or not RECOMMENDER_ENDPOINTS[rec_type]:
|
| 241 |
return jsonify({"error": "Invalid or missing recommender URL for type."}), 400
|
| 242 |
-
|
| 243 |
# JWT Authentication
|
| 244 |
auth_header = request.headers.get('Authorization')
|
| 245 |
if not auth_header or not auth_header.startswith('Bearer '):
|
| 246 |
return jsonify({"error": "Missing or invalid Authorization header"}), 401
|
| 247 |
-
|
| 248 |
token = auth_header.split(" ")[1]
|
| 249 |
try:
|
| 250 |
user_data = decode_jwt(token)
|
| 251 |
user_id = user_data.get("user_id")
|
| 252 |
except Exception as e:
|
| 253 |
return jsonify({"error": "Invalid or expired token"}), 401
|
| 254 |
-
|
| 255 |
# Call microservice
|
| 256 |
try:
|
| 257 |
recommender_url = RECOMMENDER_ENDPOINTS[rec_type]
|
|
@@ -260,20 +253,24 @@ def recommend_book():
|
|
| 260 |
json={"genre": genre}, # Single string as expected
|
| 261 |
timeout=10
|
| 262 |
)
|
| 263 |
-
|
| 264 |
if not response.ok:
|
| 265 |
return jsonify({
|
| 266 |
"error": f"{rec_type} service error",
|
| 267 |
"details": response.text,
|
| 268 |
"status_code": response.status_code
|
| 269 |
}), 500
|
| 270 |
-
|
| 271 |
result = response.json()
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
# Normalize response format
|
| 278 |
normalized = []
|
| 279 |
for item in raw_items:
|
|
@@ -285,7 +282,6 @@ def recommend_book():
|
|
| 285 |
"genre": item.get("genre", []),
|
| 286 |
"rating": item.get("rating")
|
| 287 |
})
|
| 288 |
-
|
| 289 |
# Save to history
|
| 290 |
try:
|
| 291 |
history = History(
|
|
@@ -300,7 +296,6 @@ def recommend_book():
|
|
| 300 |
except Exception as e:
|
| 301 |
print(f"Failed to save history: {e}")
|
| 302 |
# Don't fail the request if history saving fails
|
| 303 |
-
|
| 304 |
return jsonify({
|
| 305 |
"status": "success",
|
| 306 |
"recommendations": normalized,
|
|
@@ -308,12 +303,10 @@ def recommend_book():
|
|
| 308 |
"type": rec_type,
|
| 309 |
"genres": [genre] # ✅ Fixed: wrap single genre in list for consistency
|
| 310 |
}), 200
|
| 311 |
-
|
| 312 |
except requests.exceptions.Timeout:
|
| 313 |
return jsonify({"error": f"{rec_type} service timeout"}), 504
|
| 314 |
except requests.exceptions.RequestException as e:
|
| 315 |
return jsonify({"error": f"Failed to connect to {rec_type} service", "details": str(e)}), 503
|
| 316 |
-
|
| 317 |
except Exception as e:
|
| 318 |
print(f"Recommend error: {e}")
|
| 319 |
return jsonify({"error": "Internal server error"}), 500
|
|
|
|
| 226 |
def recommend_book():
|
| 227 |
try:
|
| 228 |
data = request.get_json()
|
|
|
|
| 229 |
if not data:
|
| 230 |
return jsonify({"error": "No data provided"}), 400
|
|
|
|
| 231 |
rec_type = data.get('type')
|
| 232 |
genre = data.get('genre')
|
| 233 |
top_k = data.get('top_k', 10)
|
|
|
|
| 234 |
if not rec_type or not genre:
|
| 235 |
return jsonify({"error": "Missing 'type' or 'genre'"}), 400
|
|
|
|
| 236 |
if rec_type not in RECOMMENDER_ENDPOINTS or not RECOMMENDER_ENDPOINTS[rec_type]:
|
| 237 |
return jsonify({"error": "Invalid or missing recommender URL for type."}), 400
|
|
|
|
| 238 |
# JWT Authentication
|
| 239 |
auth_header = request.headers.get('Authorization')
|
| 240 |
if not auth_header or not auth_header.startswith('Bearer '):
|
| 241 |
return jsonify({"error": "Missing or invalid Authorization header"}), 401
|
|
|
|
| 242 |
token = auth_header.split(" ")[1]
|
| 243 |
try:
|
| 244 |
user_data = decode_jwt(token)
|
| 245 |
user_id = user_data.get("user_id")
|
| 246 |
except Exception as e:
|
| 247 |
return jsonify({"error": "Invalid or expired token"}), 401
|
|
|
|
| 248 |
# Call microservice
|
| 249 |
try:
|
| 250 |
recommender_url = RECOMMENDER_ENDPOINTS[rec_type]
|
|
|
|
| 253 |
json={"genre": genre}, # Single string as expected
|
| 254 |
timeout=10
|
| 255 |
)
|
|
|
|
| 256 |
if not response.ok:
|
| 257 |
return jsonify({
|
| 258 |
"error": f"{rec_type} service error",
|
| 259 |
"details": response.text,
|
| 260 |
"status_code": response.status_code
|
| 261 |
}), 500
|
|
|
|
| 262 |
result = response.json()
|
| 263 |
+
|
| 264 |
+
# Handle different response formats
|
| 265 |
+
if isinstance(result, list):
|
| 266 |
+
# Microservice returns a direct list of books
|
| 267 |
+
raw_items = result
|
| 268 |
+
else:
|
| 269 |
+
# Microservice returns structured response with status
|
| 270 |
+
if result.get("status") != "success":
|
| 271 |
+
return jsonify({"error": result.get("message", "Unknown error")}), 500
|
| 272 |
+
raw_items = result.get(RESPONSE_KEYS.get(rec_type, "items"), [])
|
| 273 |
+
|
| 274 |
# Normalize response format
|
| 275 |
normalized = []
|
| 276 |
for item in raw_items:
|
|
|
|
| 282 |
"genre": item.get("genre", []),
|
| 283 |
"rating": item.get("rating")
|
| 284 |
})
|
|
|
|
| 285 |
# Save to history
|
| 286 |
try:
|
| 287 |
history = History(
|
|
|
|
| 296 |
except Exception as e:
|
| 297 |
print(f"Failed to save history: {e}")
|
| 298 |
# Don't fail the request if history saving fails
|
|
|
|
| 299 |
return jsonify({
|
| 300 |
"status": "success",
|
| 301 |
"recommendations": normalized,
|
|
|
|
| 303 |
"type": rec_type,
|
| 304 |
"genres": [genre] # ✅ Fixed: wrap single genre in list for consistency
|
| 305 |
}), 200
|
|
|
|
| 306 |
except requests.exceptions.Timeout:
|
| 307 |
return jsonify({"error": f"{rec_type} service timeout"}), 504
|
| 308 |
except requests.exceptions.RequestException as e:
|
| 309 |
return jsonify({"error": f"Failed to connect to {rec_type} service", "details": str(e)}), 503
|
|
|
|
| 310 |
except Exception as e:
|
| 311 |
print(f"Recommend error: {e}")
|
| 312 |
return jsonify({"error": "Internal server error"}), 500
|