Really-amin's picture
Upload 596 files
5f67151 verified
#!/usr/bin/env python3
"""
Whale Tracking Router
GET /api/whales/transactions, GET /api/whales/activity
"""
from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import JSONResponse
from typing import Optional, List, Dict, Any
from datetime import datetime, timezone, timedelta
import logging
from backend.services.provider_fallback_manager import fallback_manager
from backend.services.data_resolver import get_data_resolver
from backend.services.persistence_service import PersistenceService
from database.db_manager import db_manager
logger = logging.getLogger(__name__)
router = APIRouter(
prefix="/api/whales",
tags=["Whale Tracking"]
)
persistence_service = PersistenceService()
def create_response(data: Any, source: str, attempted: List[str] = None) -> Dict[str, Any]:
"""Create standardized response"""
return {
"data": data,
"meta": {
"source": source,
"generated_at": datetime.now(timezone.utc).isoformat(),
"cache_ttl": 60,
"attempted": attempted or [source]
}
}
@router.get("/transactions")
async def get_whale_transactions(
limit: int = Query(50, description="Number of transactions"),
chain: Optional[str] = Query(None, description="Blockchain (ethereum, bsc, tron)"),
min_amount_usd: Optional[float] = Query(100000, description="Minimum amount in USD")
):
"""Get whale transactions"""
attempted = []
# Try database first
try:
transactions = await persistence_service.get_whale_transactions(
limit=limit,
chain=chain,
min_amount=min_amount_usd
)
if transactions:
attempted.append("database")
return create_response(transactions, "database", attempted)
except Exception as e:
logger.warning(f"Database query failed: {e}")
attempted.append("database")
# Try HF Space
try:
resolver = await get_data_resolver()
whale_data = await resolver.resolve_whale_transactions(limit=limit, chain=chain)
if whale_data:
attempted.append("hf")
# Save to database
await persistence_service.save_whale_transactions(whale_data)
return create_response(whale_data, "hf", attempted)
except Exception as e:
logger.warning(f"HF Space unavailable: {e}")
attempted.append("hf")
# Fallback to external APIs
try:
result = await fallback_manager.fetch_with_fallback(
endpoint="/whale/transactions",
params={"limit": limit, "chain": chain or "ethereum"},
transform_func=lambda x: x if isinstance(x, list) else []
)
attempted.extend(result.attempted)
if result.success and result.data:
# Filter by min_amount
filtered = [
tx for tx in result.data
if tx.get("amount_usd", 0) >= min_amount_usd
]
await persistence_service.save_whale_transactions(filtered)
return create_response(filtered[:limit], result.source, attempted)
except Exception as e:
logger.error(f"External APIs failed: {e}")
attempted.append("external_apis")
# Return empty with attempted sources
return create_response([], "none", attempted)
@router.get("/activity")
async def get_whale_activity(
hours: int = Query(24, description="Hours to look back")
):
"""Get whale activity statistics"""
attempted = []
# Try database
try:
since = datetime.now(timezone.utc) - timedelta(hours=hours)
activity = await persistence_service.get_whale_activity_stats(since)
if activity:
attempted.append("database")
return create_response(activity, "database", attempted)
except Exception as e:
logger.warning(f"Database query failed: {e}")
attempted.append("database")
# Try HF Space
try:
resolver = await get_data_resolver()
activity = await resolver.resolve_whale_activity(hours=hours)
if activity:
attempted.append("hf")
return create_response(activity, "hf", attempted)
except Exception as e:
logger.warning(f"HF Space unavailable: {e}")
attempted.append("hf")
# Fallback to external
try:
result = await fallback_manager.fetch_with_fallback(
endpoint="/whale/stats",
params={"hours": hours},
transform_func=lambda x: x if isinstance(x, dict) else {}
)
attempted.extend(result.attempted)
if result.success:
return create_response(result.data, result.source, attempted)
except Exception as e:
logger.error(f"External APIs failed: {e}")
attempted.append("external_apis")
# Return default stats
default_stats = {
"total_transactions": 0,
"total_volume_usd": 0,
"top_chains": [],
"period_hours": hours
}
return create_response(default_stats, "default", attempted)