124 lines
4.2 KiB
Python
124 lines
4.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
import logging
|
|
from app.database import get_db
|
|
from app.schemas.assets import (
|
|
AssetResponse, SingleAssetResponse, AssetHistoryResponse,
|
|
AssetMarketsResponse, ErrorResponse
|
|
)
|
|
from app.services.coincap_client import CoinCapClient
|
|
|
|
router = APIRouter(prefix="/assets", tags=["Assets"])
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Initialize client
|
|
client = CoinCapClient()
|
|
|
|
@router.get(
|
|
"",
|
|
response_model=AssetResponse,
|
|
summary="Get list of assets",
|
|
description="Retrieve a list of assets with optional filters"
|
|
)
|
|
async def get_assets(
|
|
search: Optional[str] = None,
|
|
ids: Optional[str] = None,
|
|
limit: Optional[int] = Query(100, ge=1, le=2000),
|
|
offset: Optional[int] = Query(0, ge=0),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
try:
|
|
response = await client.get_assets(search=search, ids=ids, limit=limit, offset=offset)
|
|
return response
|
|
except Exception as e:
|
|
logger.error(f"Error fetching assets: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.get(
|
|
"/{slug}",
|
|
response_model=SingleAssetResponse,
|
|
responses={404: {"model": ErrorResponse}},
|
|
summary="Get a specific asset",
|
|
description="Retrieve details for a specific asset by its slug"
|
|
)
|
|
async def get_asset(slug: str, db: Session = Depends(get_db)):
|
|
try:
|
|
response = await client.get_asset(slug)
|
|
if not response.get("data"):
|
|
raise HTTPException(status_code=404, detail=f"{slug} not found")
|
|
return response
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error fetching asset {slug}: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.get(
|
|
"/{slug}/markets",
|
|
response_model=AssetMarketsResponse,
|
|
responses={404: {"model": ErrorResponse}},
|
|
summary="Get markets for an asset",
|
|
description="Retrieve markets for a specific asset"
|
|
)
|
|
async def get_asset_markets(
|
|
slug: str,
|
|
limit: Optional[int] = Query(100, ge=1, le=2000),
|
|
offset: Optional[int] = Query(0, ge=0),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
try:
|
|
response = await client.get_asset_markets(slug, limit=limit, offset=offset)
|
|
if not response.get("data") and isinstance(response.get("data"), list):
|
|
raise HTTPException(status_code=404, detail=f"{slug} not found")
|
|
return response
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error fetching markets for asset {slug}: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.get(
|
|
"/{slug}/history",
|
|
response_model=AssetHistoryResponse,
|
|
responses={404: {"model": ErrorResponse}},
|
|
summary="Get historical data for an asset",
|
|
description="Retrieve historical price data for a specific asset"
|
|
)
|
|
async def get_asset_history(
|
|
slug: str,
|
|
interval: str = Query(..., description="Time interval (m1, m5, m15, m30, h1, h2, h6, h12, d1)"),
|
|
start: Optional[int] = None,
|
|
end: Optional[int] = None,
|
|
db: Session = Depends(get_db)
|
|
):
|
|
# Validate interval
|
|
valid_intervals = ["m1", "m5", "m15", "m30", "h1", "h2", "h6", "h12", "d1"]
|
|
if interval not in valid_intervals:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Invalid interval. Must be one of: {', '.join(valid_intervals)}"
|
|
)
|
|
|
|
# Validate start and end
|
|
if (start is None and end is not None) or (start is not None and end is None):
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Both start and end must be provided together or neither should be provided"
|
|
)
|
|
|
|
try:
|
|
response = await client.get_asset_history(
|
|
slug, interval=interval, start=start, end=end
|
|
)
|
|
if not response.get("data") and isinstance(response.get("data"), list):
|
|
raise HTTPException(status_code=404, detail=f"{slug} not found")
|
|
return response
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error fetching history for asset {slug}: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e)) |