from typing import Any, List, Optional, Dict from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app import crud from app.api import deps from app.schemas.pool import Pool, PoolWithDex, PoolList router = APIRouter() @router.get("/", response_model=PoolList) def read_pools( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, sort_by_tvl: bool = True ) -> Any: """ Retrieve pools with pagination. """ result = crud.pool.get_pools_with_dex(db, skip=skip, limit=limit) pools_with_dex = [] for pool, dex in result: pools_with_dex.append(PoolWithDex( **pool.__dict__, dex_name=dex.name, dex_address=dex.address )) total = crud.pool.get_count(db) return {"pools": pools_with_dex, "total": total} @router.get("/active", response_model=PoolList) def read_most_active_pools( db: Session = Depends(deps.get_db), limit: int = Query(20, ge=1, le=100) ) -> Any: """ Get the most active pools by volume. """ pools = crud.pool.get_most_active_pools(db, limit=limit) # Add DEX information pools_with_dex = [] for p in pools: dex = crud.dex.get(db, id=p.dex_id) if dex: pools_with_dex.append(PoolWithDex( **p.__dict__, dex_name=dex.name, dex_address=dex.address )) return {"pools": pools_with_dex, "total": len(pools_with_dex)} @router.get("/{pool_id}", response_model=PoolWithDex) def read_pool( pool_id: int, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific pool by id. """ pool = crud.pool.get(db, id=pool_id) if not pool: raise HTTPException(status_code=404, detail="Pool not found") dex = crud.dex.get(db, id=pool.dex_id) if not dex: raise HTTPException(status_code=404, detail="DEX not found") return PoolWithDex( **pool.__dict__, dex_name=dex.name, dex_address=dex.address ) @router.get("/address/{address}", response_model=PoolWithDex) def read_pool_by_address( address: str, db: Session = Depends(deps.get_db), ) -> Any: """ Get a specific pool by address. """ pool = crud.pool.get_by_address(db, address=address) if not pool: raise HTTPException(status_code=404, detail="Pool not found") dex = crud.dex.get(db, id=pool.dex_id) if not dex: raise HTTPException(status_code=404, detail="DEX not found") return PoolWithDex( **pool.__dict__, dex_name=dex.name, dex_address=dex.address ) @router.get("/token/{token_address}", response_model=PoolList) def read_pools_by_token( token_address: str, db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get pools that contain a specific token. """ pools = crud.pool.get_by_token(db, token_address=token_address, skip=skip, limit=limit) # Add DEX information pools_with_dex = [] for p in pools: dex = crud.dex.get(db, id=p.dex_id) if dex: pools_with_dex.append(PoolWithDex( **p.__dict__, dex_name=dex.name, dex_address=dex.address )) return {"pools": pools_with_dex, "total": len(pools_with_dex)} @router.get("/pair", response_model=PoolList) def read_pools_by_token_pair( token_a: str = Query(...), token_b: str = Query(...), db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get pools for a specific token pair. """ pools = crud.pool.get_by_token_pair( db, token_a=token_a, token_b=token_b, skip=skip, limit=limit ) # Add DEX information pools_with_dex = [] for p in pools: dex = crud.dex.get(db, id=p.dex_id) if dex: pools_with_dex.append(PoolWithDex( **p.__dict__, dex_name=dex.name, dex_address=dex.address )) return {"pools": pools_with_dex, "total": len(pools_with_dex)} @router.get("/tvl-range", response_model=PoolList) def read_pools_by_tvl( min_tvl: float = Query(..., ge=0), max_tvl: Optional[float] = Query(None, ge=0), db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100 ) -> Any: """ Get pools within a TVL range. """ pools = crud.pool.get_by_tvl_range( db, min_tvl=min_tvl, max_tvl=max_tvl, skip=skip, limit=limit ) # Add DEX information pools_with_dex = [] for p in pools: dex = crud.dex.get(db, id=p.dex_id) if dex: pools_with_dex.append(PoolWithDex( **p.__dict__, dex_name=dex.name, dex_address=dex.address )) return {"pools": pools_with_dex, "total": len(pools_with_dex)}