from fastapi import APIRouter, Depends, HTTPException, Query, Path, status from sqlalchemy.orm import Session from typing import Optional, List import time from app.services.coincap_api import coincap_api from app.core.database import get_db from app.api.schemas.asset import ( Asset, AssetCreate, AssetResponse, AssetsResponse, AssetHistoryResponse ) router = APIRouter() @router.get("", response_model=AssetsResponse) async def get_assets( search: Optional[str] = None, ids: Optional[str] = None, limit: Optional[int] = Query(100, le=2000), offset: Optional[int] = Query(0, ge=0), db: Session = Depends(get_db) ): """ Get a list of assets with optional filters """ try: response = await coincap_api.get_assets(search, ids, limit, offset) return response except HTTPException as e: raise e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to fetch assets: {str(e)}" ) @router.get("/{asset_id}", response_model=AssetResponse) async def get_asset( asset_id: str = Path(..., description="The asset ID (slug) to retrieve"), db: Session = Depends(get_db) ): """ Get details for a specific asset by ID """ try: response = await coincap_api.get_asset(asset_id) return response except HTTPException as e: raise e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to fetch asset {asset_id}: {str(e)}" ) @router.get("/{asset_id}/markets", response_model=dict) async def get_asset_markets( asset_id: str = Path(..., description="The asset ID (slug) to retrieve markets for"), limit: Optional[int] = Query(100, le=2000), offset: Optional[int] = Query(0, ge=0), db: Session = Depends(get_db) ): """ Get markets for a specific asset """ try: response = await coincap_api.get_asset_markets(asset_id, limit, offset) return response except HTTPException as e: raise e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to fetch markets for asset {asset_id}: {str(e)}" ) @router.get("/{asset_id}/history", response_model=AssetHistoryResponse) async def get_asset_history( asset_id: str = Path(..., description="The asset ID (slug) to retrieve history for"), interval: str = Query(..., description="Interval choices: m1, m5, m15, m30, h1, h2, h6, h12, d1"), start: Optional[int] = Query(None, description="UNIX time in milliseconds"), end: Optional[int] = Query(None, description="UNIX time in milliseconds"), db: Session = Depends(get_db) ): """ Get historical data for a specific asset """ # Validate interval choices valid_intervals = ["m1", "m5", "m15", "m30", "h1", "h2", "h6", "h12", "d1"] if interval not in valid_intervals: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid interval. Choose from: {', '.join(valid_intervals)}" ) # Both start and end must be provided if one is provided if (start is None and end is not None) or (start is not None and end is None): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Both 'start' and 'end' parameters must be provided together" ) try: response = await coincap_api.get_asset_history(asset_id, interval, start, end) return response except HTTPException as e: raise e except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to fetch history for asset {asset_id}: {str(e)}" )