Automated Action 5bb78bd9be Implement Solana arbitrage analytics backend
- Create project structure with FastAPI
- Add database models for blocks, transactions, arbitrages, pools, and DEXes
- Implement Solana RPC client for fetching blockchain data
- Create arbitrage detection algorithm
- Implement comprehensive API endpoints for analytics
- Set up database migrations with Alembic
- Add detailed project documentation

generated with BackendIM... (backend.im)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-12 14:13:06 +00:00

144 lines
3.8 KiB
Python

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}