|
|
""" |
|
|
Test script for POST /recommendations/check endpoint |
|
|
Tests the new endpoint that checks user data and provides category-specific recommendations |
|
|
""" |
|
|
|
|
|
import requests |
|
|
import json |
|
|
from datetime import datetime |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BASE_URL = "https://logicgoinfotechspaces-smart-budget-recommendation.hf.space" |
|
|
|
|
|
|
|
|
TEST_USER_ID = "6741abd38d30ab5b7176397f" |
|
|
TEST_CATEGORY_ID = "6741abd38d30ab5b71763984" |
|
|
|
|
|
def test_recommendations_check_with_data(): |
|
|
"""Test POST /recommendations/check with user that has previous data""" |
|
|
print("=" * 60) |
|
|
print("Test 1: POST /recommendations/check (User with Previous Data)") |
|
|
print("=" * 60) |
|
|
|
|
|
try: |
|
|
request_body = { |
|
|
"user_id": TEST_USER_ID, |
|
|
"category_id": TEST_CATEGORY_ID |
|
|
} |
|
|
|
|
|
print(f"\nRequest Body:") |
|
|
print(json.dumps(request_body, indent=2)) |
|
|
|
|
|
response = requests.post( |
|
|
f"{BASE_URL}/recommendations/check", |
|
|
json=request_body, |
|
|
headers={"Content-Type": "application/json"} |
|
|
) |
|
|
|
|
|
print(f"\nStatus Code: {response.status_code}") |
|
|
|
|
|
if response.status_code == 200: |
|
|
result = response.json() |
|
|
print(f"\nResponse:") |
|
|
print(json.dumps(result, indent=2)) |
|
|
|
|
|
if result.get("has_previous_data"): |
|
|
print("\n[OK] User has previous data") |
|
|
if result.get("recommendations"): |
|
|
print(f"[OK] Found {len(result['recommendations'])} recommendation(s)") |
|
|
for rec in result["recommendations"]: |
|
|
print(f"\n Category: {rec.get('category')}") |
|
|
print(f" Category ID: {rec.get('category_id')}") |
|
|
print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") |
|
|
print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") |
|
|
print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") |
|
|
print(f" Action: {rec.get('action', 'N/A')}") |
|
|
print(f" Reason: {rec.get('reason', 'N/A')}") |
|
|
else: |
|
|
print("[WARNING] No recommendations returned") |
|
|
else: |
|
|
print("\n[INFO] User does not have previous data") |
|
|
print(f"Message: {result.get('message', 'N/A')}") |
|
|
|
|
|
return response.status_code == 200 |
|
|
else: |
|
|
print(f"\n[ERROR] Request failed") |
|
|
print(f"Response: {response.text}") |
|
|
return False |
|
|
|
|
|
except Exception as e: |
|
|
print(f"\n[ERROR] Exception: {e}") |
|
|
import traceback |
|
|
traceback.print_exc() |
|
|
return False |
|
|
|
|
|
def test_recommendations_check_with_budget_amount(): |
|
|
"""Test POST /recommendations/check with budget_amount provided""" |
|
|
print("\n" + "=" * 60) |
|
|
print("Test 2: POST /recommendations/check (With Budget Amount)") |
|
|
print("=" * 60) |
|
|
|
|
|
try: |
|
|
request_body = { |
|
|
"user_id": TEST_USER_ID, |
|
|
"category_id": TEST_CATEGORY_ID, |
|
|
"budget_amount": 10000.0 |
|
|
} |
|
|
|
|
|
print(f"\nRequest Body:") |
|
|
print(json.dumps(request_body, indent=2)) |
|
|
|
|
|
response = requests.post( |
|
|
f"{BASE_URL}/recommendations/check", |
|
|
json=request_body, |
|
|
headers={"Content-Type": "application/json"} |
|
|
) |
|
|
|
|
|
print(f"\nStatus Code: {response.status_code}") |
|
|
|
|
|
if response.status_code == 200: |
|
|
result = response.json() |
|
|
print(f"\nResponse:") |
|
|
print(json.dumps(result, indent=2)) |
|
|
|
|
|
if result.get("recommendations"): |
|
|
print(f"\n[OK] Generated {len(result['recommendations'])} recommendation(s) based on budget_amount") |
|
|
for rec in result["recommendations"]: |
|
|
print(f"\n Category: {rec.get('category')}") |
|
|
print(f" Category ID: {rec.get('category_id')}") |
|
|
print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") |
|
|
print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") |
|
|
print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") |
|
|
print(f" Action: {rec.get('action', 'N/A')}") |
|
|
print(f" Reason: {rec.get('reason', 'N/A')}") |
|
|
else: |
|
|
print("\n[WARNING] No recommendations returned even with budget_amount") |
|
|
|
|
|
return response.status_code == 200 |
|
|
else: |
|
|
print(f"\n[ERROR] Request failed") |
|
|
print(f"Response: {response.text}") |
|
|
return False |
|
|
|
|
|
except Exception as e: |
|
|
print(f"\n[ERROR] Exception: {e}") |
|
|
import traceback |
|
|
traceback.print_exc() |
|
|
return False |
|
|
|
|
|
def test_recommendations_check_new_user(): |
|
|
"""Test POST /recommendations/check with a new user (no previous data)""" |
|
|
print("\n" + "=" * 60) |
|
|
print("Test 3: POST /recommendations/check (New User - No Previous Data)") |
|
|
print("=" * 60) |
|
|
|
|
|
try: |
|
|
request_body = { |
|
|
"user_id": "000000000000000000000000", |
|
|
"category_id": TEST_CATEGORY_ID |
|
|
} |
|
|
|
|
|
print(f"\nRequest Body:") |
|
|
print(json.dumps(request_body, indent=2)) |
|
|
|
|
|
response = requests.post( |
|
|
f"{BASE_URL}/recommendations/check", |
|
|
json=request_body, |
|
|
headers={"Content-Type": "application/json"} |
|
|
) |
|
|
|
|
|
print(f"\nStatus Code: {response.status_code}") |
|
|
|
|
|
if response.status_code == 200: |
|
|
result = response.json() |
|
|
print(f"\nResponse:") |
|
|
print(json.dumps(result, indent=2)) |
|
|
|
|
|
if not result.get("has_previous_data"): |
|
|
print("\n[OK] Correctly identified user has no previous data") |
|
|
print(f"Message: {result.get('message', 'N/A')}") |
|
|
else: |
|
|
print("\n[WARNING] User was identified as having data (unexpected)") |
|
|
|
|
|
return response.status_code == 200 |
|
|
else: |
|
|
print(f"\n[ERROR] Request failed") |
|
|
print(f"Response: {response.text}") |
|
|
return False |
|
|
|
|
|
except Exception as e: |
|
|
print(f"\n[ERROR] Exception: {e}") |
|
|
import traceback |
|
|
traceback.print_exc() |
|
|
return False |
|
|
|
|
|
def test_recommendations_check_new_user_with_budget(): |
|
|
"""Test POST /recommendations/check with new user but with budget_amount""" |
|
|
print("\n" + "=" * 60) |
|
|
print("Test 4: POST /recommendations/check (New User with Budget Amount)") |
|
|
print("=" * 60) |
|
|
|
|
|
try: |
|
|
request_body = { |
|
|
"user_id": "000000000000000000000000", |
|
|
"category_id": TEST_CATEGORY_ID, |
|
|
"budget_amount": 5000.0 |
|
|
} |
|
|
|
|
|
print(f"\nRequest Body:") |
|
|
print(json.dumps(request_body, indent=2)) |
|
|
|
|
|
response = requests.post( |
|
|
f"{BASE_URL}/recommendations/check", |
|
|
json=request_body, |
|
|
headers={"Content-Type": "application/json"} |
|
|
) |
|
|
|
|
|
print(f"\nStatus Code: {response.status_code}") |
|
|
|
|
|
if response.status_code == 200: |
|
|
result = response.json() |
|
|
print(f"\nResponse:") |
|
|
print(json.dumps(result, indent=2)) |
|
|
|
|
|
if result.get("recommendations"): |
|
|
print(f"\n[OK] Generated recommendation for new user based on budget_amount") |
|
|
for rec in result["recommendations"]: |
|
|
print(f"\n Category: {rec.get('category')}") |
|
|
print(f" Category ID: {rec.get('category_id')}") |
|
|
print(f" Average Expense: Rs.{rec.get('average_expense', 0):,.2f}") |
|
|
print(f" Recommended Budget: Rs.{rec.get('recommended_budget', 0):,.2f}") |
|
|
print(f" Confidence: {rec.get('confidence', 0)*100:.1f}%") |
|
|
print(f" Action: {rec.get('action', 'N/A')}") |
|
|
print(f" Reason: {rec.get('reason', 'N/A')}") |
|
|
else: |
|
|
print("\n[WARNING] No recommendations returned even with budget_amount") |
|
|
|
|
|
return response.status_code == 200 |
|
|
else: |
|
|
print(f"\n[ERROR] Request failed") |
|
|
print(f"Response: {response.text}") |
|
|
return False |
|
|
|
|
|
except Exception as e: |
|
|
print(f"\n[ERROR] Exception: {e}") |
|
|
import traceback |
|
|
traceback.print_exc() |
|
|
return False |
|
|
|
|
|
if __name__ == "__main__": |
|
|
print("\n" + "=" * 60) |
|
|
print("Smart Budget Recommendation API - Test Suite") |
|
|
print("POST /recommendations/check Endpoint Tests") |
|
|
print("=" * 60) |
|
|
print(f"\nBase URL: {BASE_URL}") |
|
|
print(f"Test User ID: {TEST_USER_ID}") |
|
|
print(f"Test Category ID: {TEST_CATEGORY_ID}") |
|
|
print("\nTesting against Hugging Face deployment") |
|
|
print("(For local testing, change BASE_URL to http://localhost:8000 and start server with: uvicorn app.main:app --reload)\n") |
|
|
|
|
|
results = [] |
|
|
|
|
|
|
|
|
results.append(("User with Previous Data", test_recommendations_check_with_data())) |
|
|
results.append(("With Budget Amount", test_recommendations_check_with_budget_amount())) |
|
|
results.append(("New User (No Data)", test_recommendations_check_new_user())) |
|
|
results.append(("New User with Budget Amount", test_recommendations_check_new_user_with_budget())) |
|
|
|
|
|
|
|
|
print("\n" + "=" * 60) |
|
|
print("Test Summary") |
|
|
print("=" * 60) |
|
|
for test_name, passed in results: |
|
|
status = "[PASS]" if passed else "[FAIL]" |
|
|
print(f"{status} - {test_name}") |
|
|
|
|
|
passed_count = sum(1 for _, passed in results if passed) |
|
|
print(f"\nTotal: {passed_count}/{len(results)} tests passed") |
|
|
|
|
|
print("\n" + "=" * 60) |
|
|
print("API Documentation available at:") |
|
|
print(f" - Swagger UI: {BASE_URL}/docs") |
|
|
print(f" - ReDoc: {BASE_URL}/redoc") |
|
|
print("=" * 60) |
|
|
|
|
|
|