Skip to content

Latest commit

 

History

History
357 lines (288 loc) · 8.82 KB

File metadata and controls

357 lines (288 loc) · 8.82 KB

Migration Guide: Upgrading to Credit-Based Billing

Overview

This guide helps existing API users transition to the new credit-based billing system.

What Changed?

Before (Old System)

# No authentication required
POST /predict
{
  "features": {...}
}

After (New System)

# Authentication required
POST /predict
Headers: Authorization: Bearer <token>
{
  "features": {...}
}

Breaking Changes

⚠️ Important: The /predict endpoint now requires authentication.

Old Request (No longer works)

curl -X POST "http://localhost:8000/predict" \
  -H "Content-Type: application/json" \
  -d '{"features": {...}}'

Error: 401 Unauthorized

New Request (Required)

# Step 1: Register or Login
curl -X POST "http://localhost:8000/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your_username",
    "email": "your@email.com",
    "password": "your_password"
  }'

# Step 2: Use the token for predictions
curl -X POST "http://localhost:8000/predict" \
  -H "Authorization: Bearer <your_token>" \
  -H "Content-Type: application/json" \
  -d '{"features": {...}}'

For API Integrations

Python Integration (Before)

import requests

response = requests.post(
    "http://localhost:8000/predict",
    json={"features": {...}}
)

Python Integration (After)

import requests

# One-time: Register/Login to get token
auth_response = requests.post(
    "http://localhost:8000/login",
    params={"username": "myuser", "password": "mypass"}
)
token = auth_response.json()["access_token"]

# Store token for reuse (valid for 30 minutes)
headers = {"Authorization": f"Bearer {token}"}

# Make predictions with token
response = requests.post(
    "http://localhost:8000/predict",
    headers=headers,
    json={"features": {...}}
)

# Check remaining credits
credits = response.json()["remaining_credits"]
print(f"Credits left: {credits}")

JavaScript Integration (After)

// One-time: Get token
const loginResponse = await fetch('http://localhost:8000/login?username=myuser&password=mypass', {
    method: 'POST'
});
const { access_token } = await loginResponse.json();

// Make predictions
const response = await fetch('http://localhost:8000/predict', {
    method: 'POST',
    headers: {
        'Authorization': `Bearer ${access_token}`,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        features: {...}
    })
});

const result = await response.json();
console.log('Remaining credits:', result.remaining_credits);

Response Format Changes

Old Response

{
  "prediction": 1,
  "probability": 0.85,
  "model_path": "/path/to/model.pkl"
}

New Response

{
  "prediction": 1,
  "probability": 0.85,
  "model_path": "/path/to/model.pkl",
  "remaining_credits": 99  // ← NEW FIELD
}

Error Handling Updates

New Error: 402 Payment Required

When credits run out:

{
  "detail": "Insufficient credits. Please top up your account."
}

How to handle:

response = requests.post(url, headers=headers, json=data)

if response.status_code == 402:
    print("⚠️ Out of credits! Please contact support to top up.")
    # Implement your credit top-up logic here
elif response.status_code == 401:
    print("⚠️ Token expired. Please login again.")
    # Refresh token logic here
elif response.status_code == 200:
    result = response.json()
    print(f"✅ Prediction: {result['prediction']}")
    print(f"📊 Credits remaining: {result['remaining_credits']}")

Token Management Best Practices

1. Token Storage

# Bad: Hard-code token
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Good: Store in environment variable
import os
token = os.getenv("API_TOKEN")

# Better: Store securely and refresh when expired
class APIClient:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.token = None
        self.token_expiry = None
    
    def login(self):
        response = requests.post(
            "http://localhost:8000/login",
            params={"username": self.username, "password": self.password}
        )
        self.token = response.json()["access_token"]
        # Tokens expire in 30 minutes
        self.token_expiry = datetime.now() + timedelta(minutes=30)
    
    def get_headers(self):
        if not self.token or datetime.now() >= self.token_expiry:
            self.login()
        return {"Authorization": f"Bearer {self.token}"}
    
    def predict(self, features):
        return requests.post(
            "http://localhost:8000/predict",
            headers=self.get_headers(),
            json={"features": features}
        )

2. Credit Monitoring

class CreditMonitor:
    def __init__(self, client, warning_threshold=10):
        self.client = client
        self.warning_threshold = warning_threshold
    
    def predict_with_monitoring(self, features):
        response = self.client.predict(features)
        
        if response.status_code == 200:
            data = response.json()
            remaining = data["remaining_credits"]
            
            if remaining <= self.warning_threshold:
                print(f"⚠️ WARNING: Only {remaining} credits remaining!")
                # Send email/notification
            
            return data
        elif response.status_code == 402:
            print("❌ Out of credits!")
            # Trigger top-up workflow
            raise Exception("Insufficient credits")
        
        return None

Testing Your Migration

1. Test Registration

curl -X POST "http://localhost:8000/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "test_migration",
    "email": "test@example.com",
    "password": "testpass"
  }'

2. Test Token Authentication

# Save token from registration response
TOKEN="your_token_here"

# Test authenticated endpoint
curl -X GET "http://localhost:8000/credits" \
  -H "Authorization: Bearer $TOKEN"

3. Test Prediction with Credit Deduction

curl -X POST "http://localhost:8000/predict" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "features": {
      "Age": 45,
      "Gender": "Male"
    }
  }'

Postman Collection Update

If you're using the old Postman collection:

  1. Import new collection: api/Churn_API_Credit_System.postman_collection.json
  2. Update environment variables:
    • Add username
    • Add password
    • Add access_token (auto-filled by login request)
  3. Update existing requests:
    • Add Authorization header: Bearer {{access_token}}

Database Schema

The new User table structure:

CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    username VARCHAR UNIQUE NOT NULL,
    email VARCHAR UNIQUE NOT NULL,
    hashed_password VARCHAR NOT NULL,
    credits INTEGER DEFAULT 100 NOT NULL,
    created_at DATETIME,
    updated_at DATETIME
);

Backward Compatibility

⚠️ No backward compatibility - All users must authenticate.

Migration Path:

  1. All existing users must register accounts
  2. Update all API clients to include authentication
  3. Monitor credit usage via remaining_credits field

Rollout Strategy

Option 1: Hard Cutover (Recommended for small user base)

  1. Deploy new version
  2. Notify all users to register
  3. Provide migration script/documentation

Option 2: Gradual Migration (For large user base)

  1. Deploy authentication-optional version first
  2. Add deprecation warnings to non-authenticated requests
  3. Set cutover date
  4. Enforce authentication after cutover

Common Issues

Issue: "Could not validate credentials"

Solution: Token expired. Login again to get new token.

Issue: "Username already registered"

Solution: Use /login instead of /register.

Issue: "Insufficient credits"

Solution: Expected after 100 predictions. Implement top-up workflow.

Issue: Old integration stopped working

Solution: Update to include authentication headers (see examples above).

Support Resources

Need Help?

  1. Check the Quick Start Guide for basic setup
  2. Review API Documentation for endpoint details
  3. Run the test script: python api/test_credit_system.py
  4. Contact development team for support

Migration Timeline:

  • ✅ New dependencies installed
  • ✅ Database schema updated
  • ✅ Authentication system active
  • ✅ Credit system enforced

All clients must update to use authentication within your organization's timeline.