Spaces:
Sleeping
Sleeping
| """Streaming data simulator — generates synthetic customer events.""" | |
| import random | |
| import time | |
| from collections import deque | |
| from datetime import datetime | |
| from fastapi import APIRouter | |
| router = APIRouter() | |
| # In-memory event queue (last 100 events) | |
| event_queue: deque = deque(maxlen=100) | |
| # Realistic value ranges based on dataset statistics | |
| FEATURE_RANGES = { | |
| "Tenure": (0, 61), | |
| "CityTier": [1, 2, 3], | |
| "WarehouseToHome": (5, 36), | |
| "Gender": [0, 1], | |
| "HourSpendOnApp": (0, 5), | |
| "NumberOfDeviceRegistered": (1, 6), | |
| "SatisfactionScore": [1, 2, 3, 4, 5], | |
| "MaritalStatus": [0, 1, 2], | |
| "NumberOfAddress": (1, 22), | |
| "Complain": [0, 1], | |
| "OrderAmountHikeFromlastYear": (11, 26), | |
| "CouponUsed": (0, 16), | |
| "OrderCount": (1, 16), | |
| "DaySinceLastOrder": (0, 46), | |
| "CashbackAmount": (0, 325), | |
| } | |
| def _generate_customer() -> dict: | |
| """Generate a random customer with realistic feature values.""" | |
| customer = {} | |
| for feat, vals in FEATURE_RANGES.items(): | |
| if isinstance(vals, list): | |
| customer[feat] = random.choice(vals) | |
| else: | |
| low, high = vals | |
| customer[feat] = round(random.uniform(low, high), 2) | |
| # Derived features | |
| tenure = customer["Tenure"] | |
| if tenure <= 6: | |
| customer["tenure_bucket"] = 0 | |
| elif tenure <= 12: | |
| customer["tenure_bucket"] = 1 | |
| elif tenure <= 24: | |
| customer["tenure_bucket"] = 2 | |
| else: | |
| customer["tenure_bucket"] = 3 | |
| customer["engagement_score"] = round(customer["HourSpendOnApp"] * customer["OrderCount"], 2) | |
| customer["cashback_per_order"] = ( | |
| round(customer["CashbackAmount"] / customer["OrderCount"], 2) | |
| if customer["OrderCount"] > 0 | |
| else 0 | |
| ) | |
| customer["is_recent_buyer"] = 1 if customer["DaySinceLastOrder"] <= 3 else 0 | |
| customer["has_multi_device"] = 1 if customer["NumberOfDeviceRegistered"] >= 4 else 0 | |
| customer["is_high_spender"] = 1 if customer["OrderAmountHikeFromlastYear"] > 20 else 0 | |
| # One-hot encoded features (random selection) | |
| login_device = random.choice(["Computer", "Mobile Phone"]) | |
| customer["PreferredLoginDevice_Mobile Phone"] = 1 if login_device == "Mobile Phone" else 0 | |
| payment = random.choice(["Cash on Delivery", "Credit Card", "Debit Card", "E wallet", "UPI"]) | |
| customer["PreferredPaymentMode_Credit Card"] = 1 if payment == "Credit Card" else 0 | |
| customer["PreferredPaymentMode_Debit Card"] = 1 if payment == "Debit Card" else 0 | |
| customer["PreferredPaymentMode_E wallet"] = 1 if payment == "E wallet" else 0 | |
| customer["PreferredPaymentMode_UPI"] = 1 if payment == "UPI" else 0 | |
| category = random.choice(["Fashion", "Grocery", "Laptop & Accessory", "Mobile Phone", "Others"]) | |
| customer["PreferedOrderCat_Grocery"] = 1 if category == "Grocery" else 0 | |
| customer["PreferedOrderCat_Laptop & Accessory"] = 1 if category == "Laptop & Accessory" else 0 | |
| customer["PreferedOrderCat_Mobile Phone"] = 1 if category == "Mobile Phone" else 0 | |
| customer["PreferedOrderCat_Others"] = 1 if category == "Others" else 0 | |
| return customer | |
| def generate_event(): | |
| """Generate a single synthetic customer event and add to the queue.""" | |
| customer = _generate_customer() | |
| event = { | |
| "timestamp": datetime.now().isoformat(), | |
| "customer": customer, | |
| } | |
| event_queue.append(event) | |
| return {"status": "generated", "event": event} | |
| def generate_batch(count: int = 10): | |
| """Generate multiple synthetic customer events.""" | |
| events = [] | |
| for _ in range(min(count, 50)): | |
| customer = _generate_customer() | |
| event = { | |
| "timestamp": datetime.now().isoformat(), | |
| "customer": customer, | |
| } | |
| event_queue.append(event) | |
| events.append(event) | |
| return {"status": "generated", "count": len(events), "events": events} | |
| def get_events(limit: int = 20): | |
| """Get recent events from the queue.""" | |
| events = list(event_queue)[-limit:] | |
| return {"count": len(events), "events": events} | |
| def get_stats(): | |
| """Get streaming statistics.""" | |
| return { | |
| "total_events": len(event_queue), | |
| "queue_capacity": event_queue.maxlen, | |
| } | |