Skip to content

Latest commit

Β 

History

History
400 lines (318 loc) Β· 8.47 KB

File metadata and controls

400 lines (318 loc) Β· 8.47 KB

Quick Command Reference: Credit System

πŸš€ Setup Commands

1. Install Dependencies

cd api
pip install -r requirements.txt

2. Run Database Migration

# Migrate existing database (adds credits column)
python api/migrate_add_credits.py

# Or with custom database path
python api/migrate_add_credits.py /path/to/database.db

3. Start API Server

uvicorn api.main:app --reload --host 0.0.0.0 --port 8000

πŸ§ͺ Testing Commands

Register New User (100 Free Credits)

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

# Save the access_token from response

Login Existing User

curl -X POST "http://localhost:8000/login?username=alice&password=password123"

# Save the access_token from response

Check Credit Balance

curl -X GET "http://localhost:8000/credits" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE"

Make Prediction (Costs 1 Credit)

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

Run Automated Tests

python api/test_credit_system.py

πŸ” Verification Commands

Check Database Schema

import sqlite3
conn = sqlite3.connect('api/churn_api.db')
cursor = conn.cursor()
cursor.execute("PRAGMA table_info(users)")
for row in cursor.fetchall():
    print(row)
conn.close()

Check User Credits in Database

import sqlite3
conn = sqlite3.connect('api/churn_api.db')
cursor = conn.cursor()
cursor.execute("SELECT id, username, email, credits FROM users")
for row in cursor.fetchall():
    print(f"ID: {row[0]}, User: {row[1]}, Email: {row[2]}, Credits: {row[3]}")
conn.close()

View API Documentation

# Start server, then visit:
# Swagger UI: http://localhost:8000/docs
# ReDoc: http://localhost:8000/redoc

πŸ’Ύ Database Commands

Backup Database

cp api/churn_api.db api/churn_api.db.backup_$(date +%Y%m%d_%H%M%S)

Restore from Backup

cp api/churn_api.db.backup_TIMESTAMP api/churn_api.db

Reset Database (Delete All Data)

rm api/churn_api.db
# Tables will be recreated on next API start

Manually Update Credits (Testing Only)

import sqlite3
conn = sqlite3.connect('api/churn_api.db')
cursor = conn.cursor()

# Set specific user to 0 credits (to test 402 error)
cursor.execute("UPDATE users SET credits = 0 WHERE username = 'alice'")
conn.commit()

# Give user more credits
cursor.execute("UPDATE users SET credits = 100 WHERE username = 'alice'")
conn.commit()

conn.close()

πŸ“ PowerShell Commands (Windows)

Setup

# Activate virtual environment
.\.venv\Scripts\Activate.ps1

# Install dependencies
cd api
pip install -r requirements.txt

# Run migration
python migrate_add_credits.py

# Start server
uvicorn main:app --reload --host 0.0.0.0 --port 8000

Testing

# Register user
$body = @{
    username = "alice"
    email = "alice@example.com"
    password = "password123"
} | ConvertTo-Json

Invoke-RestMethod -Uri "http://localhost:8000/register" `
    -Method POST `
    -ContentType "application/json" `
    -Body $body

# Save token
$token = "YOUR_TOKEN_HERE"

# Check credits
Invoke-RestMethod -Uri "http://localhost:8000/credits" `
    -Method GET `
    -Headers @{Authorization="Bearer $token"}

# Make prediction
$features = @{
    features = @{
        Age = 45
        Gender = "Male"
        Tenure = 24
    }
} | ConvertTo-Json

Invoke-RestMethod -Uri "http://localhost:8000/predict" `
    -Method POST `
    -ContentType "application/json" `
    -Headers @{Authorization="Bearer $token"} `
    -Body $features

🐍 Python Integration

Simple Client

import requests

class ChurnAPIClient:
    def __init__(self, base_url="http://localhost:8000"):
        self.base_url = base_url
        self.token = None
    
    def register(self, username, email, password):
        """Register new user with 100 free credits."""
        response = requests.post(
            f"{self.base_url}/register",
            json={"username": username, "email": email, "password": password}
        )
        self.token = response.json()["access_token"]
        return self.token
    
    def login(self, username, password):
        """Login existing user."""
        response = requests.post(
            f"{self.base_url}/login",
            params={"username": username, "password": password}
        )
        self.token = response.json()["access_token"]
        return self.token
    
    def get_credits(self):
        """Check current credit balance."""
        response = requests.get(
            f"{self.base_url}/credits",
            headers={"Authorization": f"Bearer {self.token}"}
        )
        return response.json()
    
    def predict(self, features):
        """Make a prediction (costs 1 credit)."""
        response = requests.post(
            f"{self.base_url}/predict",
            headers={"Authorization": f"Bearer {self.token}"},
            json={"features": features}
        )
        return response.json()

# Usage
client = ChurnAPIClient()
client.register("alice", "alice@example.com", "password123")

# Check credits
credits = client.get_credits()
print(f"Credits: {credits['credits']}")

# Make prediction
result = client.predict({
    "Age": 45,
    "Gender": "Male",
    "Tenure": 24
})
print(f"Prediction: {result['prediction']}")
print(f"Remaining: {result['remaining_credits']}")

πŸ“Š Monitoring Commands

Watch Credits in Real-Time

# Linux/Mac
watch -n 2 'curl -s -H "Authorization: Bearer TOKEN" http://localhost:8000/credits'

# Windows PowerShell
while($true) {
    Invoke-RestMethod -Uri "http://localhost:8000/credits" `
        -Headers @{Authorization="Bearer $token"}
    Start-Sleep -Seconds 2
    Clear-Host
}

Count Total Users

sqlite3 api/churn_api.db "SELECT COUNT(*) FROM users"

Show Users with Low Credits

sqlite3 api/churn_api.db "SELECT username, credits FROM users WHERE credits < 10"

πŸ”§ Troubleshooting Commands

Check if API is Running

curl http://localhost:8000/health
# Expected: {"status": "ok"}

Verify Model is Loaded

curl http://localhost:8000/schema
# Expected: {"expects": "...", "required_columns": [...]}

Test Without Authentication (Should Fail)

curl -X POST "http://localhost:8000/predict" \
  -H "Content-Type: application/json" \
  -d '{"features": {}}'
# Expected: 401 Unauthorized or 403 Forbidden

Check Server Logs

# If running with uvicorn --reload
# Logs appear in terminal

# If running in background
tail -f nohup.out  # Linux/Mac
Get-Content -Path .\logs.txt -Wait  # Windows

🎯 One-Line Test Suite

# Complete test in one command
python api/test_credit_system.py && echo "βœ… All tests passed!" || echo "❌ Tests failed"

πŸ“¦ Export/Import Users

Export Users to CSV

import sqlite3
import csv

conn = sqlite3.connect('api/churn_api.db')
cursor = conn.cursor()
cursor.execute("SELECT id, username, email, credits FROM users")

with open('users_export.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['ID', 'Username', 'Email', 'Credits'])
    writer.writerows(cursor.fetchall())

conn.close()
print("βœ… Exported to users_export.csv")

Update Credits from CSV

import sqlite3
import csv

conn = sqlite3.connect('api/churn_api.db')
cursor = conn.cursor()

with open('users_update.csv', 'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        cursor.execute(
            "UPDATE users SET credits = ? WHERE username = ?",
            (row['credits'], row['username'])
        )

conn.commit()
conn.close()
print("βœ… Credits updated from CSV")

πŸ”‘ Environment Variables

# .env file (optional)
DATABASE_URL=sqlite:///./churn_api.db
SECRET_KEY=your-secret-key-change-in-production
MLFLOW_EXPERIMENT_NAME=customer_churn_optimization
BEST_MODEL_METRIC=f1

# Load in shell
export $(cat .env | xargs)  # Linux/Mac
Get-Content .env | ForEach-Object { [System.Environment]::SetEnvironmentVariable($_.Split('=')[0], $_.Split('=')[1]) }  # Windows

For more details, see FINALIZATION_GUIDE.md