from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app import crud from app.api import deps from app.schemas.dex import Dex, DexWithPoolCount, DexList from app.schemas.pool import Pool, PoolList router = APIRouter() @router.get("/", response_model=DexList) def read_dexes( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, sort_by_volume: bool = False ) -> Any: """ Retrieve DEXes with pagination. """ if sort_by_volume: # Get DEXes sorted by volume dexes_with_count = [] dexes = crud.dex.get_with_volumes(db, skip=skip, limit=limit) for d in dexes: pool_count = len(crud.pool.get_by_dex(db, dex_id=d.id, limit=1000)) dexes_with_count.append(DexWithPoolCount( **d.__dict__, pool_count=pool_count )) else: # Get DEXes with pool count dexes_with_count = [] result = crud.dex.get_with_pool_count(db, skip=skip, limit=limit) for dex, pool_count in result: dexes_with_count.append(DexWithPoolCount( **dex.__dict__, pool_count=pool_count )) total = crud.dex.get_count(db) return {"dexes": dexes_with_count, "total": total} @router.get("/{dex_id}", response_model=Dex) def read_dex( dex_id: int, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific DEX by id. """ dex = crud.dex.get(db, id=dex_id) if not dex: raise HTTPException(status_code=404, detail="DEX not found") return dex @router.get("/address/{address}", response_model=Dex) def read_dex_by_address( address: str, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific DEX by address. """ dex = crud.dex.get_by_address(db, address=address) if not dex: raise HTTPException(status_code=404, detail="DEX not found") return dex @router.get("/name/{name}", response_model=Dex) def read_dex_by_name( name: str, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific DEX by name. """ dex = crud.dex.get_by_name(db, name=name) if not dex: raise HTTPException(status_code=404, detail="DEX not found") return dex @router.get("/search", response_model=DexList) def search_dexes( query: str = Query(..., min_length=2), db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Search DEXes by name. """ dexes = crud.dex.search_by_name(db, query=query, skip=skip, limit=limit) # Add pool counts dexes_with_count = [] for d in dexes: pool_count = len(crud.pool.get_by_dex(db, dex_id=d.id, limit=1000)) dexes_with_count.append(DexWithPoolCount( **d.__dict__, pool_count=pool_count )) # This is a simplified count for demo purposes total = len(dexes) return {"dexes": dexes_with_count, "total": total} @router.get("/{dex_id}/pools", response_model=PoolList) def read_dex_pools( dex_id: int, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get pools for a specific DEX. """ dex = crud.dex.get(db, id=dex_id) if not dex: raise HTTPException(status_code=404, detail="DEX not found") pools = crud.pool.get_by_dex(db, dex_id=dex_id, skip=skip, limit=limit) # Add DEX information to each pool pools_with_dex = [] for p in pools: pools_with_dex.append({ **p.__dict__, "dex_name": dex.name, "dex_address": dex.address }) # Count total pools for this DEX total = len(crud.pool.get_by_dex(db, dex_id=dex_id, limit=1000)) return {"pools": pools_with_dex, "total": total}