from typing import Any, List, Optional from datetime import datetime, timedelta from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app import crud from app.api import deps from app.schemas.arbitrage import ( Arbitrage, ArbitrageWithLegs, ArbitrageList, ArbitrageStats ) router = APIRouter() @router.get("/", response_model=ArbitrageList) def read_arbitrages( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, successful: Optional[bool] = None ) -> Any: """ Retrieve arbitrages with pagination. """ if successful is not None: if successful: arbitrages = crud.arbitrage.get_successful_arbitrages( db, skip=skip, limit=limit ) else: arbitrages = crud.arbitrage.get_failed_arbitrages( db, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) else: arbitrages = crud.arbitrage.get_multi(db, skip=skip, limit=limit) total = crud.arbitrage.get_count(db) return {"arbitrages": arbitrages, "total": total} @router.get("/stats", response_model=ArbitrageStats) def read_arbitrage_stats( db: Session = Depends(deps.get_db), ) -> Any: """ Get overall arbitrage statistics. """ stats = crud.arbitrage.get_arbitrage_stats(db) return stats @router.get("/{arbitrage_id}", response_model=ArbitrageWithLegs) def read_arbitrage( arbitrage_id: int, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific arbitrage with details of all legs. """ arbitrage = crud.arbitrage.get_with_legs(db, arbitrage_id=arbitrage_id) if not arbitrage: raise HTTPException(status_code=404, detail="Arbitrage not found") return arbitrage @router.get("/initiator/{initiator_address}", response_model=ArbitrageList) def read_arbitrages_by_initiator( initiator_address: str, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get arbitrages initiated by a specific address. """ arbitrages = crud.arbitrage.get_by_initiator( db, initiator=initiator_address, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) return {"arbitrages": arbitrages, "total": total} @router.get("/token/{token_address}", response_model=ArbitrageList) def read_arbitrages_by_token( token_address: str, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get arbitrages involving a specific token. """ arbitrages = crud.arbitrage.get_by_token( db, token=token_address, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) return {"arbitrages": arbitrages, "total": total} @router.get("/profit-range", response_model=ArbitrageList) def read_arbitrages_by_profit( min_profit: float = Query(..., ge=0), max_profit: Optional[float] = Query(None, ge=0), db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get arbitrages within a profit percentage range. """ arbitrages = crud.arbitrage.get_arbitrages_by_profit_range( db, min_profit=min_profit, max_profit=max_profit, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) return {"arbitrages": arbitrages, "total": total} @router.get("/time-range", response_model=ArbitrageList) def read_arbitrages_by_time( start_time: datetime = Query(...), end_time: Optional[datetime] = None, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get arbitrages within a time range. """ if end_time is None: end_time = datetime.utcnow() arbitrages = crud.arbitrage.get_arbitrages_by_time_range( db, start_time=start_time, end_time=end_time, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) return {"arbitrages": arbitrages, "total": total} @router.get("/dex/{dex_id}", response_model=ArbitrageList) def read_arbitrages_by_dex( dex_id: int, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get arbitrages involving a specific DEX. """ arbitrages = crud.arbitrage.get_arbitrages_by_dex( db, dex_id=dex_id, skip=skip, limit=limit ) # This is a simplified count for demo purposes total = len(arbitrages) return {"arbitrages": arbitrages, "total": total}