razorshield-api / src /inference /preprocessing.py
Vedant Sanjay Jadhav
feat: complete RazorShield AI risk platform
10ec54c
Raw
History Blame Contribute Delete
2.36 kB
"""
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(),
)