frankscore-model / test.py
Gutema-1990
the model artifact is removed to be deployed separately
97b9b33
#!/usr/bin/env python3
"""
Test script for /v1/predict endpoint.
This script demonstrates the correct request format:
- inputId: required string
- payload: object containing the feature data
"""
import hmac
import hashlib
import time
import uuid
import requests
# ============================================
# CONFIGURATION (from tenant creation)
# ============================================
CLIENT_ID = "acme-bank-463edc0a"
CLIENT_SECRET = "yPqsrtBizHgDvnK-NpkgVXMXw3WbV_s_JGK-c2pWr3U"
HMAC_SECRET = "OSSBJgx2QToeQhGtQgzwS_8Kf1QvTraq6M67uNrBKEo"
BASE_URL = "https://frankscore-backend.onrender.com"
# ============================================
# STEP 1: Login as Tenant
# ============================================
print("Step 1: Logging in...")
login_response = requests.post(
f"{BASE_URL}/auth/login",
json={
"clientId": CLIENT_ID,
"clientSecret": CLIENT_SECRET
}
)
if login_response.status_code != 200:
print(f"❌ Login failed: {login_response.status_code}")
print(login_response.text)
exit(1)
login_data = login_response.json()
jwt_token = login_data["access_token"] # Note: camelCase, not snake_case
print(f"βœ… Logged in. JWT: {jwt_token[:20]}...")
# ============================================
# STEP 2: Prepare End-User Identity
# ============================================
end_user_id = "user-alice-123" # Your customer
timestamp = str(int(time.time()))
request_id = str(uuid.uuid4())
# ============================================
# STEP 3: Compute HMAC Signature
# ============================================
signing_string = f"{end_user_id}|{timestamp}|{request_id}"
signature = hmac.new(
HMAC_SECRET.encode('utf-8'), # SECRET KEY (never sent!)
signing_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
print(f"πŸ“ Signing string: {signing_string}")
print(f"πŸ” Signature: {signature[:20]}...")
# ============================================
# STEP 4: Make Prediction Request
# ============================================
print("\nStep 4: Making prediction request...")
# IMPORTANT: The request format is:
# {
# "inputId": "string", # REQUIRED
# "payload": { ... } # The features go here
# }
request_body = {
"inputId": "loan-app-78945", # REQUIRED - unique identifier for this request
"payload": {
"num_previous_loans": 9,
"num_previous_defaults": 4,
"past_default_rate": 0.44,
"days_since_last_loan": 2,
"avg_time_bw_loans": 20,
"avg_past_amount": 26000,
"avg_past_daily_burden": 950,
"std_past_amount": 4000,
"std_past_daily_burden": 180,
"trend_in_amount": 1.3,
"trend_in_burden": 1.35,
"Total_Amount": 30000,
"Total_Amount_to_Repay": 36000,
"duration": 20,
"daily_burden": 1500,
"amount_ratio": 2.0,
"burden_ratio": 1.8,
"duration_bucket": "20",
"amount_bucket": "high",
"burden_percentile": 0.95,
"borrower_history_strength": "weak",
"month": 1,
"quarter": 1,
"week_of_year": 3,
"days_to_salary_day": 28,
"days_to_local_festival": 2,
"lender_id": "L_high3",
"lender_exposure_ratio": 0.4,
"account_age_days": 150,
"loan_frequency_per_year": 12,
"repayment_consistency": 0.4,
"latest_amount_ma3": 28000
}
}
response = requests.post(
f"{BASE_URL}/v1/predict_explain",
headers={
"Authorization": f"Bearer {jwt_token}",
"Content-Type": "application/json",
"X-End-User-Id": end_user_id,
"X-End-User-Timestamp": timestamp,
"X-Request-Id": request_id,
"X-End-User-Signature": signature
},
json=request_body
)
print(f"\nResponse Status: {response.status_code}")
if response.status_code == 200:
result = response.json()
print("βœ… Prediction successful!")
print(f" Input ID: {result.get('inputId')}")
print(f" Score: {result.get('score')}")
if result.get('topFeatures'):
print(f" Top Features: {len(result.get('topFeatures'))} features")
print(f"\nFull response: {result}")
else:
print(f"❌ Prediction failed: {response.status_code}")
print(response.text)