Spaces:
Running on Zero
Running on Zero
| """ | |
| preprocessing.py | |
| ---------------- | |
| Data cleaning and validation helpers for incoming API transaction payloads. | |
| """ | |
| from __future__ import annotations | |
| from datetime import datetime | |
| import logging | |
| from typing import Any | |
| from src.api.schemas import TransactionApiInput | |
| LOGGER = logging.getLogger("inference-preprocessing") | |
| def validate_raw_api_payload(payload: dict[str, Any]) -> TransactionApiInput: | |
| """ | |
| Validates and cleans incoming raw API request dictionary. | |
| Raises ValueError if required fields are missing or invalid. | |
| """ | |
| if not isinstance(payload, dict): | |
| raise ValueError("Invalid request payload: Must be a JSON object.") | |
| # Amount check | |
| amount = payload.get("amount") | |
| if amount is None or not isinstance(amount, (int, float)) or amount < 0: | |
| raise ValueError(f"Invalid transaction amount: {amount}. Amount must be a non-negative float.") | |
| # Event time check | |
| event_time_raw = payload.get("event_time") | |
| if isinstance(event_time_raw, str): | |
| try: | |
| event_time = datetime.fromisoformat(event_time_raw.replace("Z", "+00:00")) | |
| except Exception: | |
| raise ValueError(f"Malformed event_time timestamp: '{event_time_raw}'. Must be ISO 8601 format.") | |
| elif isinstance(event_time_raw, datetime): | |
| event_time = event_time_raw | |
| else: | |
| raise ValueError("Missing or invalid 'event_time' timestamp.") | |
| merchant_id = payload.get("merchant_id") | |
| transaction_id = payload.get("transaction_id") | |
| if not merchant_id or not str(merchant_id).strip(): | |
| raise ValueError("Missing required field 'merchant_id'.") | |
| if not transaction_id or not str(transaction_id).strip(): | |
| raise ValueError("Missing required field 'transaction_id'.") | |
| return TransactionApiInput( | |
| merchant_id=str(merchant_id).strip(), | |
| transaction_id=str(transaction_id).strip(), | |
| customer_id=str(payload.get("customer_id", "C_UNKNOWN")).strip(), | |
| device_id=str(payload.get("device_id", "D_UNKNOWN")).strip(), | |
| event_time=event_time, | |
| amount=float(amount), | |
| payment_method=str(payload.get("payment_method", "card")).lower().strip(), | |
| transaction_type=str(payload.get("transaction_type", "sale")).lower().strip(), | |
| policy_mode=str(payload.get("policy_mode", "BALANCED")).upper().strip(), | |
| ) | |