|
|
|
|
|
|
|
|
from fastapi import APIRouter, HTTPException, Query, Path, Body
|
|
|
from typing import Optional, Dict, Any, List
|
|
|
from datetime import datetime, timezone
|
|
|
import logging
|
|
|
|
|
|
from backend.services.expanded_providers import (
|
|
|
get_provider_manager,
|
|
|
initialize_providers,
|
|
|
fetch_market_data,
|
|
|
fetch_fear_greed,
|
|
|
fetch_news,
|
|
|
fetch_ohlcv,
|
|
|
get_all_provider_health,
|
|
|
ProviderCategory,
|
|
|
PROVIDER_REGISTRY
|
|
|
)
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
router = APIRouter(
|
|
|
prefix="/api/providers/expanded",
|
|
|
tags=["Expanded Providers"]
|
|
|
)
|
|
|
|
|
|
|
|
|
def create_response(data: Any, source: str, meta: Dict = None) -> Dict[str, Any]:
|
|
|
return {
|
|
|
"success": True,
|
|
|
"data": data,
|
|
|
"meta": {
|
|
|
"source": source,
|
|
|
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
|
**(meta or {})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
@router.get("/initialize")
|
|
|
async def init_providers():
|
|
|
try:
|
|
|
result = initialize_providers()
|
|
|
return create_response(result, "expanded_providers")
|
|
|
except Exception as e:
|
|
|
logger.error(f"Failed to initialize providers: {e}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/list")
|
|
|
async def list_providers(
|
|
|
category: Optional[str] = Query(None, description="Filter by category")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
manager.initialize()
|
|
|
|
|
|
providers = []
|
|
|
for pid, provider in manager.get_all_providers().items():
|
|
|
if category and provider.config.category.value != category:
|
|
|
continue
|
|
|
providers.append({
|
|
|
"id": pid,
|
|
|
"name": provider.config.name,
|
|
|
"category": provider.config.category.value,
|
|
|
"base_url": provider.config.base_url,
|
|
|
"free_tier": provider.config.free_tier,
|
|
|
"requires_auth": provider.config.requires_auth,
|
|
|
"rate_limit": provider.config.rate_limit_per_minute,
|
|
|
"priority": provider.config.priority
|
|
|
})
|
|
|
|
|
|
return create_response(
|
|
|
providers,
|
|
|
"expanded_providers",
|
|
|
{"total": len(providers)}
|
|
|
)
|
|
|
except Exception as e:
|
|
|
logger.error(f"Failed to list providers: {e}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/categories")
|
|
|
async def list_categories():
|
|
|
try:
|
|
|
categories = [{"id": c.value, "name": c.name} for c in ProviderCategory]
|
|
|
return create_response(categories, "expanded_providers")
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/health")
|
|
|
async def get_providers_health():
|
|
|
try:
|
|
|
health = get_all_provider_health()
|
|
|
|
|
|
online = sum(1 for h in health if h["status"] == "online")
|
|
|
offline = sum(1 for h in health if h["status"] == "error")
|
|
|
unknown = sum(1 for h in health if h["status"] == "unknown")
|
|
|
|
|
|
return create_response(
|
|
|
health,
|
|
|
"expanded_providers",
|
|
|
{
|
|
|
"total": len(health),
|
|
|
"online": online,
|
|
|
"offline": offline,
|
|
|
"unknown": unknown
|
|
|
}
|
|
|
)
|
|
|
except Exception as e:
|
|
|
logger.error(f"Failed to get provider health: {e}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/health/{provider_id}")
|
|
|
async def get_provider_health(provider_id: str = Path(...)):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider(provider_id)
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail=f"Provider {provider_id} not found")
|
|
|
|
|
|
health = provider.get_health()
|
|
|
return create_response({
|
|
|
"id": provider_id,
|
|
|
"name": provider.config.name,
|
|
|
"status": health.status,
|
|
|
"latency_ms": health.latency_ms,
|
|
|
"last_check": health.last_check,
|
|
|
"error_message": health.error_message,
|
|
|
"success_rate": health.success_rate
|
|
|
}, provider.config.name)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/{provider_id}/fetch")
|
|
|
async def fetch_from_provider(
|
|
|
provider_id: str = Path(...),
|
|
|
endpoint: Optional[str] = Query(None),
|
|
|
symbol: Optional[str] = Query(None),
|
|
|
limit: Optional[int] = Query(100)
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider(provider_id)
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail=f"Provider {provider_id} not found")
|
|
|
|
|
|
kwargs = {}
|
|
|
if endpoint:
|
|
|
kwargs["endpoint"] = endpoint
|
|
|
if symbol:
|
|
|
kwargs["symbol"] = symbol
|
|
|
kwargs["symbols"] = [symbol]
|
|
|
kwargs["limit"] = limit
|
|
|
|
|
|
result = await provider.fetch_data(**kwargs)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error", "Provider request failed"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
provider.config.name,
|
|
|
{"latency_ms": result.get("latency_ms")}
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
logger.error(f"Failed to fetch from {provider_id}: {e}")
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/market/prices")
|
|
|
async def get_market_prices(
|
|
|
symbols: str = Query("bitcoin,ethereum", description="Comma-separated coin IDs")
|
|
|
):
|
|
|
try:
|
|
|
symbol_list = [s.strip() for s in symbols.split(",")]
|
|
|
result = await fetch_market_data(symbol_list)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
result.get("provider", "unknown"),
|
|
|
{"latency_ms": result.get("latency_ms")}
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/market/fear-greed")
|
|
|
async def get_fear_greed_index():
|
|
|
try:
|
|
|
result = await fetch_fear_greed()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
result.get("provider", "alternative_me")
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/news/latest")
|
|
|
async def get_latest_news():
|
|
|
try:
|
|
|
result = await fetch_news()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
result.get("provider", "cryptopanic")
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/market/ohlcv/{symbol}")
|
|
|
async def get_ohlcv_data(
|
|
|
symbol: str = Path(...),
|
|
|
interval: str = Query("1h", description="Candle interval")
|
|
|
):
|
|
|
try:
|
|
|
result = await fetch_ohlcv(symbol, interval)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
result.get("provider", "unknown")
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/blockchain/{chain}/balance/{address}")
|
|
|
async def get_blockchain_balance(
|
|
|
chain: str = Path(..., description="blockchain: ethereum, bsc, tron"),
|
|
|
address: str = Path(...)
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
|
|
|
provider_map = {
|
|
|
"ethereum": "etherscan_0",
|
|
|
"eth": "etherscan_0",
|
|
|
"bsc": "bscscan",
|
|
|
"binance": "bscscan",
|
|
|
"tron": "tronscan",
|
|
|
"trx": "tronscan"
|
|
|
}
|
|
|
|
|
|
provider_id = provider_map.get(chain.lower())
|
|
|
if not provider_id:
|
|
|
raise HTTPException(status_code=400, detail=f"Unsupported chain: {chain}")
|
|
|
|
|
|
provider = manager.get_provider(provider_id)
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail=f"Provider for {chain} not found")
|
|
|
|
|
|
if hasattr(provider, "get_balance"):
|
|
|
result = await provider.get_balance(address)
|
|
|
else:
|
|
|
result = await provider.fetch_data(address=address)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(
|
|
|
result.get("data"),
|
|
|
provider.config.name
|
|
|
)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/blockchain/{chain}/gas")
|
|
|
async def get_gas_price(chain: str = Path(...)):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
|
|
|
if chain.lower() in ["ethereum", "eth"]:
|
|
|
provider = manager.get_provider("etherscan_0")
|
|
|
if provider and hasattr(provider, "get_gas_price"):
|
|
|
result = await provider.get_gas_price()
|
|
|
if result.get("success"):
|
|
|
return create_response(result.get("data"), provider.config.name)
|
|
|
|
|
|
raise HTTPException(status_code=400, detail=f"Gas price not available for {chain}")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/social/reddit/{subreddit}")
|
|
|
async def get_reddit_posts(
|
|
|
subreddit: str = Path(...),
|
|
|
sort: str = Query("hot", description="hot, new, top, rising"),
|
|
|
limit: int = Query(25, le=100)
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("reddit")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="Reddit provider not available")
|
|
|
|
|
|
result = await provider.get_subreddit_posts(subreddit, sort, limit)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "reddit")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/defi/protocols")
|
|
|
async def get_defi_protocols():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("defillama")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="DefiLlama provider not available")
|
|
|
|
|
|
result = await provider.get_protocols()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "defillama")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/defi/tvl")
|
|
|
async def get_total_tvl():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("defillama")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="DefiLlama provider not available")
|
|
|
|
|
|
result = await provider.get_tvl_history()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "defillama")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/dex/pairs/{token_address}")
|
|
|
async def get_dex_pairs(token_address: str = Path(...)):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("dexscreener")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="DexScreener provider not available")
|
|
|
|
|
|
result = await provider.get_token_pairs(token_address)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "dexscreener")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/exchange/{exchange}/ticker")
|
|
|
async def get_exchange_ticker(
|
|
|
exchange: str = Path(...),
|
|
|
symbol: str = Query(..., description="Trading pair symbol")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
|
|
|
exchange_map = {
|
|
|
"binance": "binance",
|
|
|
"kraken": "kraken",
|
|
|
"bybit": "bybit",
|
|
|
"okx": "okx",
|
|
|
"htx": "htx",
|
|
|
"huobi": "htx",
|
|
|
"gateio": "gateio",
|
|
|
"gate": "gateio",
|
|
|
"kucoin": "kucoin"
|
|
|
}
|
|
|
|
|
|
provider_id = exchange_map.get(exchange.lower())
|
|
|
if not provider_id:
|
|
|
raise HTTPException(status_code=400, detail=f"Unsupported exchange: {exchange}")
|
|
|
|
|
|
provider = manager.get_provider(provider_id)
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail=f"Provider for {exchange} not found")
|
|
|
|
|
|
if hasattr(provider, "get_ticker"):
|
|
|
result = await provider.get_ticker(symbol)
|
|
|
else:
|
|
|
result = await provider.fetch_data(symbol=symbol)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), provider.config.name)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/exchange/{exchange}/orderbook")
|
|
|
async def get_exchange_orderbook(
|
|
|
exchange: str = Path(...),
|
|
|
symbol: str = Query(...),
|
|
|
limit: int = Query(100, le=1000)
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider(exchange.lower())
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail=f"Provider for {exchange} not found")
|
|
|
|
|
|
if hasattr(provider, "get_orderbook"):
|
|
|
result = await provider.get_orderbook(symbol, limit)
|
|
|
else:
|
|
|
raise HTTPException(status_code=400, detail=f"Orderbook not available for {exchange}")
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), provider.config.name)
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/metrics/global")
|
|
|
async def get_global_metrics():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
|
|
|
coingecko = manager.get_provider("coingecko")
|
|
|
if coingecko:
|
|
|
result = await coingecko.get_global()
|
|
|
if result.get("success"):
|
|
|
return create_response(result.get("data"), "coingecko")
|
|
|
|
|
|
coinpaprika = manager.get_provider("coinpaprika")
|
|
|
if coinpaprika:
|
|
|
result = await coinpaprika.get_global()
|
|
|
if result.get("success"):
|
|
|
return create_response(result.get("data"), "coinpaprika")
|
|
|
|
|
|
raise HTTPException(status_code=502, detail="No provider available for global metrics")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/trending")
|
|
|
async def get_trending_coins():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coingecko")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinGecko provider not available")
|
|
|
|
|
|
result = await provider.get_trending()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coingecko")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.post("/batch/prices")
|
|
|
async def batch_get_prices(
|
|
|
request: Dict[str, Any] = Body(...)
|
|
|
):
|
|
|
try:
|
|
|
symbols = request.get("symbols", ["bitcoin", "ethereum"])
|
|
|
vs_currencies = request.get("vs_currencies", "usd")
|
|
|
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coingecko")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinGecko provider not available")
|
|
|
|
|
|
result = await provider.get_prices(symbols, vs_currencies)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coingecko")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/news/crypto")
|
|
|
async def get_crypto_news_newsapi(
|
|
|
query: str = Query("cryptocurrency OR bitcoin OR ethereum", description="Search query")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("newsapi")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="NewsAPI provider not available")
|
|
|
|
|
|
result = await provider.get_crypto_news(query)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "newsapi")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/news/headlines")
|
|
|
async def get_news_headlines(
|
|
|
category: str = Query("business", description="News category")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("newsapi")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="NewsAPI provider not available")
|
|
|
|
|
|
result = await provider.get_top_headlines(category)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "newsapi")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/market/cmc/listings")
|
|
|
async def get_cmc_listings(
|
|
|
limit: int = Query(100, le=5000, description="Number of listings")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coinmarketcap")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinMarketCap provider not available")
|
|
|
|
|
|
result = await provider.get_listings(limit)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coinmarketcap")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/market/cmc/quotes/{symbols}")
|
|
|
async def get_cmc_quotes(
|
|
|
symbols: str = Path(..., description="Comma-separated symbols like BTC,ETH")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coinmarketcap")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinMarketCap provider not available")
|
|
|
|
|
|
symbol_list = [s.strip().upper() for s in symbols.split(",")]
|
|
|
result = await provider.get_latest_quotes(symbol_list)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coinmarketcap")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/market/cmc/global")
|
|
|
async def get_cmc_global_metrics():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coinmarketcap")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinMarketCap provider not available")
|
|
|
|
|
|
result = await provider.get_global_metrics()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coinmarketcap")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/market/cmc/trending")
|
|
|
async def get_cmc_trending():
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("coinmarketcap")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="CoinMarketCap provider not available")
|
|
|
|
|
|
result = await provider.get_trending()
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "coinmarketcap")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/sentiment/external")
|
|
|
async def get_external_sentiment(
|
|
|
symbol: str = Query("BTC", description="Cryptocurrency symbol")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("sentiment_api")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="Sentiment API provider not available")
|
|
|
|
|
|
result = await provider.get_market_sentiment(symbol)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "sentiment_api")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|
|
|
@router.get("/v1/sentiment/social")
|
|
|
async def get_social_sentiment(
|
|
|
symbol: str = Query("BTC", description="Cryptocurrency symbol")
|
|
|
):
|
|
|
try:
|
|
|
manager = get_provider_manager()
|
|
|
provider = manager.get_provider("sentiment_api")
|
|
|
|
|
|
if not provider:
|
|
|
raise HTTPException(status_code=404, detail="Sentiment API provider not available")
|
|
|
|
|
|
result = await provider.get_social_sentiment(symbol)
|
|
|
|
|
|
if not result.get("success"):
|
|
|
raise HTTPException(status_code=502, detail=result.get("error"))
|
|
|
|
|
|
return create_response(result.get("data"), "sentiment_api")
|
|
|
except HTTPException:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
|