nimazasinich
Cursor Agent
bxsfy712
commited on
Commit
·
ab02ac4
1
Parent(s):
8ff9278
Crypto API investigation (#117)
Browse files* feat: Add HuggingFace Crypto Resources API client and configs
Co-authored-by: bxsfy712 <[email protected]>
* feat: Add HuggingFace Space Crypto API client and router
Co-authored-by: bxsfy712 <[email protected]>
* feat: Add HuggingFace Space Crypto API client guide
Co-authored-by: bxsfy712 <[email protected]>
* feat: Add comprehensive API reference documentation
Co-authored-by: bxsfy712 <[email protected]>
---------
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: bxsfy712 <[email protected]>
- COMPLETE_API_REFERENCE.md +888 -0
- HF_SPACE_CRYPTO_API_GUIDE.md +666 -0
- backend/routers/hf_space_crypto_api.py +451 -0
- backend/services/hf_space_crypto_client.py +336 -0
- backend/services/multi_source_config.json +41 -0
- collectors/__init__.py +6 -0
- collectors/hf_crypto_api_client.py +347 -0
- config/api_keys.json +37 -0
- config/service_registry.json +69 -3
- hf_unified_server.py +8 -0
COMPLETE_API_REFERENCE.md
ADDED
|
@@ -0,0 +1,888 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete API Reference - All Available Services
|
| 2 |
+
|
| 3 |
+
## راهنمای کامل API - تمام سرویسهای موجود
|
| 4 |
+
|
| 5 |
+
**Base URL:** `http://localhost:7860`
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## 📋 Table of Contents
|
| 10 |
+
|
| 11 |
+
1. [Market Data & Prices](#1-market-data--prices)
|
| 12 |
+
2. [OHLCV / Candlestick Data](#2-ohlcv--candlestick-data)
|
| 13 |
+
3. [Technical Indicators](#3-technical-indicators)
|
| 14 |
+
4. [Sentiment Analysis](#4-sentiment-analysis)
|
| 15 |
+
5. [News & Headlines](#5-news--headlines)
|
| 16 |
+
6. [Blockchain & On-Chain Data](#6-blockchain--on-chain-data)
|
| 17 |
+
7. [Whale Tracking](#7-whale-tracking)
|
| 18 |
+
8. [AI & Machine Learning](#8-ai--machine-learning)
|
| 19 |
+
9. [HuggingFace Space Crypto API](#9-huggingface-space-crypto-api)
|
| 20 |
+
10. [System & Monitoring](#10-system--monitoring)
|
| 21 |
+
|
| 22 |
+
---
|
| 23 |
+
|
| 24 |
+
## 1. Market Data & Prices
|
| 25 |
+
|
| 26 |
+
### 1.1 Get Single Price
|
| 27 |
+
```bash
|
| 28 |
+
GET /api/market/price?symbol=BTC
|
| 29 |
+
```
|
| 30 |
+
**Parameters:**
|
| 31 |
+
- `symbol` (required): Cryptocurrency symbol (BTC, ETH, etc.)
|
| 32 |
+
|
| 33 |
+
**Example:**
|
| 34 |
+
```bash
|
| 35 |
+
curl "http://localhost:7860/api/market/price?symbol=BTC"
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
**Response:**
|
| 39 |
+
```json
|
| 40 |
+
{
|
| 41 |
+
"symbol": "BTC",
|
| 42 |
+
"price": 90241.00,
|
| 43 |
+
"source": "coingecko",
|
| 44 |
+
"timestamp": 1702406543
|
| 45 |
+
}
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
---
|
| 49 |
+
|
| 50 |
+
### 1.2 Get Multiple Prices (Multi-Source)
|
| 51 |
+
```bash
|
| 52 |
+
GET /api/multi-source/prices?symbols=BTC,ETH,BNB&limit=100
|
| 53 |
+
```
|
| 54 |
+
**Parameters:**
|
| 55 |
+
- `symbols` (optional): Comma-separated symbols
|
| 56 |
+
- `limit` (optional): Max results (1-250, default: 100)
|
| 57 |
+
- `cross_check` (optional): Validate across sources (default: true)
|
| 58 |
+
|
| 59 |
+
**Example:**
|
| 60 |
+
```bash
|
| 61 |
+
curl "http://localhost:7860/api/multi-source/prices?symbols=BTC,ETH&limit=10"
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
---
|
| 65 |
+
|
| 66 |
+
### 1.3 Get Top Coins
|
| 67 |
+
```bash
|
| 68 |
+
GET /api/service/top?limit=100
|
| 69 |
+
GET /api/hf-space/coins/top?limit=50
|
| 70 |
+
```
|
| 71 |
+
**Parameters:**
|
| 72 |
+
- `limit` (optional): Number of coins (default: 100)
|
| 73 |
+
|
| 74 |
+
**Example:**
|
| 75 |
+
```bash
|
| 76 |
+
curl "http://localhost:7860/api/hf-space/coins/top?limit=10"
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
---
|
| 80 |
+
|
| 81 |
+
### 1.4 Get Trending Coins
|
| 82 |
+
```bash
|
| 83 |
+
GET /api/trending
|
| 84 |
+
GET /api/hf-space/trending
|
| 85 |
+
GET /coingecko/trending
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
**Example:**
|
| 89 |
+
```bash
|
| 90 |
+
curl "http://localhost:7860/api/hf-space/trending"
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
### 1.5 Get Market Overview
|
| 96 |
+
```bash
|
| 97 |
+
GET /api/market
|
| 98 |
+
GET /api/hf-space/market
|
| 99 |
+
GET /api/service/market-status
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
**Example:**
|
| 103 |
+
```bash
|
| 104 |
+
curl "http://localhost:7860/api/hf-space/market"
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
**Response:**
|
| 108 |
+
```json
|
| 109 |
+
{
|
| 110 |
+
"total_market_cap": 3152683901788,
|
| 111 |
+
"total_volume": 148435101985,
|
| 112 |
+
"market_cap_percentage": {
|
| 113 |
+
"btc": 57.09,
|
| 114 |
+
"eth": 11.77
|
| 115 |
+
},
|
| 116 |
+
"active_cryptocurrencies": 19190
|
| 117 |
+
}
|
| 118 |
+
```
|
| 119 |
+
|
| 120 |
+
---
|
| 121 |
+
|
| 122 |
+
## 2. OHLCV / Candlestick Data
|
| 123 |
+
|
| 124 |
+
### 2.1 Get OHLCV Data
|
| 125 |
+
```bash
|
| 126 |
+
GET /api/market/ohlc?symbol=BTC&timeframe=1h
|
| 127 |
+
GET /api/multi-source/ohlc/{symbol}?timeframe=1h&limit=1000
|
| 128 |
+
GET /api/trading/ohlcv/{symbol}?interval=1h&limit=100
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
**Parameters:**
|
| 132 |
+
- `symbol` (required): Cryptocurrency symbol
|
| 133 |
+
- `timeframe/interval` (optional): 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w
|
| 134 |
+
- `limit` (optional): Number of candles (default: 100-1000)
|
| 135 |
+
|
| 136 |
+
**Example:**
|
| 137 |
+
```bash
|
| 138 |
+
# Get 100 hourly candles for BTC
|
| 139 |
+
curl "http://localhost:7860/api/multi-source/ohlc/BTC?timeframe=1h&limit=100"
|
| 140 |
+
|
| 141 |
+
# Get 4-hour candles for ETH
|
| 142 |
+
curl "http://localhost:7860/api/market/ohlc?symbol=ETH&timeframe=4h"
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
**Response:**
|
| 146 |
+
```json
|
| 147 |
+
{
|
| 148 |
+
"symbol": "BTC",
|
| 149 |
+
"timeframe": "1h",
|
| 150 |
+
"data": [
|
| 151 |
+
{
|
| 152 |
+
"timestamp": 1702400000000,
|
| 153 |
+
"open": 90100.00,
|
| 154 |
+
"high": 90500.00,
|
| 155 |
+
"low": 89800.00,
|
| 156 |
+
"close": 90241.00,
|
| 157 |
+
"volume": 1234567890
|
| 158 |
+
}
|
| 159 |
+
],
|
| 160 |
+
"source": "binance"
|
| 161 |
+
}
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
---
|
| 165 |
+
|
| 166 |
+
### 2.2 Get Historical Data
|
| 167 |
+
```bash
|
| 168 |
+
GET /api/market/history?symbol=BTC&days=30
|
| 169 |
+
GET /api/service/history?symbol=BTC&timeframe=1h
|
| 170 |
+
```
|
| 171 |
+
|
| 172 |
+
**Parameters:**
|
| 173 |
+
- `symbol` (required): Cryptocurrency symbol
|
| 174 |
+
- `days` (optional): Number of days (default: 30)
|
| 175 |
+
- `timeframe` (optional): 1h, 4h, 1d
|
| 176 |
+
|
| 177 |
+
---
|
| 178 |
+
|
| 179 |
+
## 3. Technical Indicators
|
| 180 |
+
|
| 181 |
+
### 3.1 RSI (Relative Strength Index)
|
| 182 |
+
```bash
|
| 183 |
+
GET /api/indicators/rsi?symbol=BTC&timeframe=1h&period=14
|
| 184 |
+
```
|
| 185 |
+
|
| 186 |
+
**Parameters:**
|
| 187 |
+
- `symbol` (optional): Default "BTC"
|
| 188 |
+
- `timeframe` (optional): 1m, 5m, 15m, 1h, 4h, 1d
|
| 189 |
+
- `period` (optional): RSI period (default: 14)
|
| 190 |
+
|
| 191 |
+
**Example:**
|
| 192 |
+
```bash
|
| 193 |
+
curl "http://localhost:7860/api/indicators/rsi?symbol=BTC&timeframe=1h&period=14"
|
| 194 |
+
```
|
| 195 |
+
|
| 196 |
+
**Response:**
|
| 197 |
+
```json
|
| 198 |
+
{
|
| 199 |
+
"success": true,
|
| 200 |
+
"symbol": "BTC",
|
| 201 |
+
"timeframe": "1h",
|
| 202 |
+
"indicator": "rsi",
|
| 203 |
+
"data": {
|
| 204 |
+
"value": 55.23
|
| 205 |
+
},
|
| 206 |
+
"signal": "neutral",
|
| 207 |
+
"description": "RSI at 55.23 - neutral zone"
|
| 208 |
+
}
|
| 209 |
+
```
|
| 210 |
+
|
| 211 |
+
---
|
| 212 |
+
|
| 213 |
+
### 3.2 MACD
|
| 214 |
+
```bash
|
| 215 |
+
GET /api/indicators/macd?symbol=BTC&timeframe=1h&fast=12&slow=26&signal_period=9
|
| 216 |
+
```
|
| 217 |
+
|
| 218 |
+
**Parameters:**
|
| 219 |
+
- `symbol`, `timeframe`
|
| 220 |
+
- `fast` (optional): Fast EMA period (default: 12)
|
| 221 |
+
- `slow` (optional): Slow EMA period (default: 26)
|
| 222 |
+
- `signal_period` (optional): Signal line period (default: 9)
|
| 223 |
+
|
| 224 |
+
**Example:**
|
| 225 |
+
```bash
|
| 226 |
+
curl "http://localhost:7860/api/indicators/macd?symbol=BTC&timeframe=1h"
|
| 227 |
+
```
|
| 228 |
+
|
| 229 |
+
**Response:**
|
| 230 |
+
```json
|
| 231 |
+
{
|
| 232 |
+
"success": true,
|
| 233 |
+
"symbol": "BTC",
|
| 234 |
+
"indicator": "macd",
|
| 235 |
+
"data": {
|
| 236 |
+
"macd_line": 50.0,
|
| 237 |
+
"signal_line": 45.0,
|
| 238 |
+
"histogram": 5.0
|
| 239 |
+
},
|
| 240 |
+
"trend": "bullish",
|
| 241 |
+
"signal": "buy"
|
| 242 |
+
}
|
| 243 |
+
```
|
| 244 |
+
|
| 245 |
+
---
|
| 246 |
+
|
| 247 |
+
### 3.3 Bollinger Bands
|
| 248 |
+
```bash
|
| 249 |
+
GET /api/indicators/bollinger-bands?symbol=BTC&timeframe=1h&period=20&std_dev=2
|
| 250 |
+
```
|
| 251 |
+
|
| 252 |
+
**Parameters:**
|
| 253 |
+
- `symbol`, `timeframe`
|
| 254 |
+
- `period` (optional): Period (default: 20)
|
| 255 |
+
- `std_dev` (optional): Standard deviation multiplier (default: 2.0)
|
| 256 |
+
|
| 257 |
+
**Example:**
|
| 258 |
+
```bash
|
| 259 |
+
curl "http://localhost:7860/api/indicators/bollinger-bands?symbol=BTC&timeframe=1h"
|
| 260 |
+
```
|
| 261 |
+
|
| 262 |
+
**Response:**
|
| 263 |
+
```json
|
| 264 |
+
{
|
| 265 |
+
"success": true,
|
| 266 |
+
"symbol": "BTC",
|
| 267 |
+
"indicator": "bollinger_bands",
|
| 268 |
+
"data": {
|
| 269 |
+
"upper": 92500.00,
|
| 270 |
+
"middle": 90241.00,
|
| 271 |
+
"lower": 88000.00,
|
| 272 |
+
"bandwidth": 4.98,
|
| 273 |
+
"percent_b": 50.0
|
| 274 |
+
},
|
| 275 |
+
"signal": "neutral"
|
| 276 |
+
}
|
| 277 |
+
```
|
| 278 |
+
|
| 279 |
+
---
|
| 280 |
+
|
| 281 |
+
### 3.4 SMA (Simple Moving Average)
|
| 282 |
+
```bash
|
| 283 |
+
GET /api/indicators/sma?symbol=BTC&timeframe=1h
|
| 284 |
+
```
|
| 285 |
+
|
| 286 |
+
**Response:**
|
| 287 |
+
```json
|
| 288 |
+
{
|
| 289 |
+
"success": true,
|
| 290 |
+
"data": {
|
| 291 |
+
"sma20": 89500.00,
|
| 292 |
+
"sma50": 87200.00,
|
| 293 |
+
"sma200": 75000.00
|
| 294 |
+
},
|
| 295 |
+
"trend": "bullish",
|
| 296 |
+
"signal": "buy"
|
| 297 |
+
}
|
| 298 |
+
```
|
| 299 |
+
|
| 300 |
+
---
|
| 301 |
+
|
| 302 |
+
### 3.5 EMA (Exponential Moving Average)
|
| 303 |
+
```bash
|
| 304 |
+
GET /api/indicators/ema?symbol=BTC&timeframe=1h
|
| 305 |
+
```
|
| 306 |
+
|
| 307 |
+
**Response:**
|
| 308 |
+
```json
|
| 309 |
+
{
|
| 310 |
+
"success": true,
|
| 311 |
+
"data": {
|
| 312 |
+
"ema12": 90100.00,
|
| 313 |
+
"ema26": 89500.00,
|
| 314 |
+
"ema50": 87000.00
|
| 315 |
+
},
|
| 316 |
+
"trend": "bullish"
|
| 317 |
+
}
|
| 318 |
+
```
|
| 319 |
+
|
| 320 |
+
---
|
| 321 |
+
|
| 322 |
+
### 3.6 Stochastic RSI
|
| 323 |
+
```bash
|
| 324 |
+
GET /api/indicators/stoch-rsi?symbol=BTC&timeframe=1h&rsi_period=14&stoch_period=14
|
| 325 |
+
```
|
| 326 |
+
|
| 327 |
+
**Response:**
|
| 328 |
+
```json
|
| 329 |
+
{
|
| 330 |
+
"success": true,
|
| 331 |
+
"data": {
|
| 332 |
+
"value": 65.5,
|
| 333 |
+
"k_line": 65.5,
|
| 334 |
+
"d_line": 60.2
|
| 335 |
+
},
|
| 336 |
+
"signal": "neutral"
|
| 337 |
+
}
|
| 338 |
+
```
|
| 339 |
+
|
| 340 |
+
---
|
| 341 |
+
|
| 342 |
+
### 3.7 ATR (Average True Range)
|
| 343 |
+
```bash
|
| 344 |
+
GET /api/indicators/atr?symbol=BTC&timeframe=1h&period=14
|
| 345 |
+
```
|
| 346 |
+
|
| 347 |
+
**Response:**
|
| 348 |
+
```json
|
| 349 |
+
{
|
| 350 |
+
"success": true,
|
| 351 |
+
"data": {
|
| 352 |
+
"value": 1500.00,
|
| 353 |
+
"percent": 1.66
|
| 354 |
+
},
|
| 355 |
+
"volatility_level": "medium"
|
| 356 |
+
}
|
| 357 |
+
```
|
| 358 |
+
|
| 359 |
+
---
|
| 360 |
+
|
| 361 |
+
### 3.8 Comprehensive Analysis (ALL Indicators)
|
| 362 |
+
```bash
|
| 363 |
+
GET /api/indicators/comprehensive?symbol=BTC&timeframe=1h
|
| 364 |
+
```
|
| 365 |
+
|
| 366 |
+
**Example:**
|
| 367 |
+
```bash
|
| 368 |
+
curl "http://localhost:7860/api/indicators/comprehensive?symbol=BTC&timeframe=1h"
|
| 369 |
+
```
|
| 370 |
+
|
| 371 |
+
**Response:**
|
| 372 |
+
```json
|
| 373 |
+
{
|
| 374 |
+
"success": true,
|
| 375 |
+
"symbol": "BTC",
|
| 376 |
+
"current_price": 90241.00,
|
| 377 |
+
"indicators": {
|
| 378 |
+
"bollinger_bands": {"upper": 92500, "middle": 90241, "lower": 88000},
|
| 379 |
+
"stoch_rsi": {"value": 55, "k_line": 55, "d_line": 52},
|
| 380 |
+
"atr": {"value": 1500, "percent": 1.66},
|
| 381 |
+
"sma": {"sma20": 89500, "sma50": 87200, "sma200": 75000},
|
| 382 |
+
"ema": {"ema12": 90100, "ema26": 89500},
|
| 383 |
+
"macd": {"macd_line": 50, "signal_line": 45, "histogram": 5},
|
| 384 |
+
"rsi": {"value": 55}
|
| 385 |
+
},
|
| 386 |
+
"signals": {
|
| 387 |
+
"bollinger_bands": "neutral",
|
| 388 |
+
"stoch_rsi": "neutral",
|
| 389 |
+
"sma": "bullish",
|
| 390 |
+
"ema": "bullish",
|
| 391 |
+
"macd": "bullish",
|
| 392 |
+
"rsi": "neutral"
|
| 393 |
+
},
|
| 394 |
+
"overall_signal": "BUY",
|
| 395 |
+
"confidence": 70,
|
| 396 |
+
"recommendation": "Majority bullish signals - favorable conditions for entry"
|
| 397 |
+
}
|
| 398 |
+
```
|
| 399 |
+
|
| 400 |
+
---
|
| 401 |
+
|
| 402 |
+
### 3.9 List All Indicator Services
|
| 403 |
+
```bash
|
| 404 |
+
GET /api/indicators/services
|
| 405 |
+
```
|
| 406 |
+
|
| 407 |
+
---
|
| 408 |
+
|
| 409 |
+
## 4. Sentiment Analysis
|
| 410 |
+
|
| 411 |
+
### 4.1 Fear & Greed Index
|
| 412 |
+
```bash
|
| 413 |
+
GET /api/hf-space/sentiment
|
| 414 |
+
GET /api/multi-source/sentiment
|
| 415 |
+
GET /api/sentiment/global
|
| 416 |
+
GET /alternative/fng
|
| 417 |
+
```
|
| 418 |
+
|
| 419 |
+
**Example:**
|
| 420 |
+
```bash
|
| 421 |
+
curl "http://localhost:7860/api/hf-space/sentiment"
|
| 422 |
+
```
|
| 423 |
+
|
| 424 |
+
**Response:**
|
| 425 |
+
```json
|
| 426 |
+
{
|
| 427 |
+
"fear_greed_index": 29,
|
| 428 |
+
"sentiment": "fear",
|
| 429 |
+
"market_mood": "bearish",
|
| 430 |
+
"confidence": 0.85,
|
| 431 |
+
"source": "alternative.me"
|
| 432 |
+
}
|
| 433 |
+
```
|
| 434 |
+
|
| 435 |
+
---
|
| 436 |
+
|
| 437 |
+
### 4.2 Analyze Text Sentiment (AI)
|
| 438 |
+
```bash
|
| 439 |
+
POST /api/sentiment/analyze
|
| 440 |
+
POST /hf/sentiment
|
| 441 |
+
```
|
| 442 |
+
|
| 443 |
+
**Body:**
|
| 444 |
+
```json
|
| 445 |
+
{
|
| 446 |
+
"text": "Bitcoin is going to the moon! Very bullish!"
|
| 447 |
+
}
|
| 448 |
+
```
|
| 449 |
+
|
| 450 |
+
**Example:**
|
| 451 |
+
```bash
|
| 452 |
+
curl -X POST "http://localhost:7860/api/sentiment/analyze" \
|
| 453 |
+
-H "Content-Type: application/json" \
|
| 454 |
+
-d '{"text": "Bitcoin is going to the moon!"}'
|
| 455 |
+
```
|
| 456 |
+
|
| 457 |
+
**Response:**
|
| 458 |
+
```json
|
| 459 |
+
{
|
| 460 |
+
"text": "Bitcoin is going to the moon!",
|
| 461 |
+
"sentiment": "bullish",
|
| 462 |
+
"score": 0.92,
|
| 463 |
+
"confidence": 0.87,
|
| 464 |
+
"model": "CryptoBERT"
|
| 465 |
+
}
|
| 466 |
+
```
|
| 467 |
+
|
| 468 |
+
---
|
| 469 |
+
|
| 470 |
+
### 4.3 Bulk Sentiment Analysis
|
| 471 |
+
```bash
|
| 472 |
+
POST /hf/sentiment/batch
|
| 473 |
+
```
|
| 474 |
+
|
| 475 |
+
**Body:**
|
| 476 |
+
```json
|
| 477 |
+
{
|
| 478 |
+
"texts": [
|
| 479 |
+
"BTC is going up!",
|
| 480 |
+
"ETH crash incoming",
|
| 481 |
+
"Market looks stable"
|
| 482 |
+
]
|
| 483 |
+
}
|
| 484 |
+
```
|
| 485 |
+
|
| 486 |
+
---
|
| 487 |
+
|
| 488 |
+
### 4.4 Asset-Specific Sentiment
|
| 489 |
+
```bash
|
| 490 |
+
GET /api/hf-space/sentiment/{symbol}
|
| 491 |
+
GET /api/resources/sentiment/coin/{symbol}
|
| 492 |
+
```
|
| 493 |
+
|
| 494 |
+
**Example:**
|
| 495 |
+
```bash
|
| 496 |
+
curl "http://localhost:7860/api/hf-space/sentiment/BTC"
|
| 497 |
+
```
|
| 498 |
+
|
| 499 |
+
---
|
| 500 |
+
|
| 501 |
+
## 5. News & Headlines
|
| 502 |
+
|
| 503 |
+
### 5.1 Get Latest News
|
| 504 |
+
```bash
|
| 505 |
+
GET /api/multi-source/news?query=cryptocurrency&limit=50
|
| 506 |
+
GET /api/news/latest
|
| 507 |
+
GET /api/hf-space/resources/category/news_apis
|
| 508 |
+
```
|
| 509 |
+
|
| 510 |
+
**Parameters:**
|
| 511 |
+
- `query` (optional): Search query (default: "cryptocurrency")
|
| 512 |
+
- `limit` (optional): Max articles (default: 50)
|
| 513 |
+
- `aggregate` (optional): Combine from multiple sources (default: true)
|
| 514 |
+
|
| 515 |
+
**Example:**
|
| 516 |
+
```bash
|
| 517 |
+
curl "http://localhost:7860/api/multi-source/news?query=bitcoin&limit=20"
|
| 518 |
+
```
|
| 519 |
+
|
| 520 |
+
**Response:**
|
| 521 |
+
```json
|
| 522 |
+
{
|
| 523 |
+
"articles": [
|
| 524 |
+
{
|
| 525 |
+
"title": "Bitcoin Reaches New High",
|
| 526 |
+
"description": "...",
|
| 527 |
+
"url": "https://...",
|
| 528 |
+
"source": "CoinDesk",
|
| 529 |
+
"publishedAt": "2025-12-12T10:00:00Z"
|
| 530 |
+
}
|
| 531 |
+
],
|
| 532 |
+
"total": 20,
|
| 533 |
+
"sources_used": ["coindesk", "cointelegraph", "cryptopanic"]
|
| 534 |
+
}
|
| 535 |
+
```
|
| 536 |
+
|
| 537 |
+
---
|
| 538 |
+
|
| 539 |
+
### 5.2 Get Headlines
|
| 540 |
+
```bash
|
| 541 |
+
GET /api/news/headlines
|
| 542 |
+
```
|
| 543 |
+
|
| 544 |
+
---
|
| 545 |
+
|
| 546 |
+
### 5.3 RSS Feeds
|
| 547 |
+
```bash
|
| 548 |
+
GET /rss/all
|
| 549 |
+
GET /rss/feed?url=https://cointelegraph.com/rss
|
| 550 |
+
GET /coindesk/rss
|
| 551 |
+
GET /cointelegraph/rss
|
| 552 |
+
```
|
| 553 |
+
|
| 554 |
+
**Example:**
|
| 555 |
+
```bash
|
| 556 |
+
curl "http://localhost:7860/rss/all"
|
| 557 |
+
```
|
| 558 |
+
|
| 559 |
+
---
|
| 560 |
+
|
| 561 |
+
## 6. Blockchain & On-Chain Data
|
| 562 |
+
|
| 563 |
+
### 6.1 Gas Prices
|
| 564 |
+
```bash
|
| 565 |
+
GET /api/blockchain/gas
|
| 566 |
+
GET /api/resources/onchain/gas
|
| 567 |
+
GET /api/crypto/blockchain/gas
|
| 568 |
+
```
|
| 569 |
+
|
| 570 |
+
**Example:**
|
| 571 |
+
```bash
|
| 572 |
+
curl "http://localhost:7860/api/blockchain/gas"
|
| 573 |
+
```
|
| 574 |
+
|
| 575 |
+
**Response:**
|
| 576 |
+
```json
|
| 577 |
+
{
|
| 578 |
+
"chain": "ethereum",
|
| 579 |
+
"gas": {
|
| 580 |
+
"slow": 20,
|
| 581 |
+
"standard": 25,
|
| 582 |
+
"fast": 35,
|
| 583 |
+
"instant": 50
|
| 584 |
+
},
|
| 585 |
+
"unit": "gwei"
|
| 586 |
+
}
|
| 587 |
+
```
|
| 588 |
+
|
| 589 |
+
---
|
| 590 |
+
|
| 591 |
+
### 6.2 Blockchain Stats
|
| 592 |
+
```bash
|
| 593 |
+
GET /api/blockchain/{chain}
|
| 594 |
+
GET /api/blockchain/stats
|
| 595 |
+
```
|
| 596 |
+
|
| 597 |
+
**Parameters:**
|
| 598 |
+
- `chain`: ethereum, bsc, tron
|
| 599 |
+
|
| 600 |
+
**Example:**
|
| 601 |
+
```bash
|
| 602 |
+
curl "http://localhost:7860/api/blockchain/ethereum"
|
| 603 |
+
```
|
| 604 |
+
|
| 605 |
+
---
|
| 606 |
+
|
| 607 |
+
### 6.3 Transaction Data
|
| 608 |
+
```bash
|
| 609 |
+
GET /api/blockchain/transactions?address={address}
|
| 610 |
+
GET /api/resources/onchain/transactions?address={address}&chain=ethereum
|
| 611 |
+
```
|
| 612 |
+
|
| 613 |
+
---
|
| 614 |
+
|
| 615 |
+
### 6.4 Address Balance
|
| 616 |
+
```bash
|
| 617 |
+
GET /api/resources/onchain/balance?address={address}&chain=ethereum
|
| 618 |
+
```
|
| 619 |
+
|
| 620 |
+
---
|
| 621 |
+
|
| 622 |
+
## 7. Whale Tracking
|
| 623 |
+
|
| 624 |
+
### 7.1 Whale Transactions
|
| 625 |
+
```bash
|
| 626 |
+
GET /api/whales/transactions
|
| 627 |
+
GET /api/service/whales
|
| 628 |
+
```
|
| 629 |
+
|
| 630 |
+
**Example:**
|
| 631 |
+
```bash
|
| 632 |
+
curl "http://localhost:7860/api/service/whales"
|
| 633 |
+
```
|
| 634 |
+
|
| 635 |
+
**Response:**
|
| 636 |
+
```json
|
| 637 |
+
{
|
| 638 |
+
"transactions": [
|
| 639 |
+
{
|
| 640 |
+
"hash": "0x...",
|
| 641 |
+
"from": "0x...",
|
| 642 |
+
"to": "0x...",
|
| 643 |
+
"value": "1000 BTC",
|
| 644 |
+
"timestamp": "2025-12-12T10:00:00Z"
|
| 645 |
+
}
|
| 646 |
+
],
|
| 647 |
+
"total": 10
|
| 648 |
+
}
|
| 649 |
+
```
|
| 650 |
+
|
| 651 |
+
---
|
| 652 |
+
|
| 653 |
+
### 7.2 Whale Stats
|
| 654 |
+
```bash
|
| 655 |
+
GET /api/whales/stats
|
| 656 |
+
```
|
| 657 |
+
|
| 658 |
+
---
|
| 659 |
+
|
| 660 |
+
## 8. AI & Machine Learning
|
| 661 |
+
|
| 662 |
+
### 8.1 Available AI Models
|
| 663 |
+
```bash
|
| 664 |
+
GET /api/models/list
|
| 665 |
+
GET /hf/models
|
| 666 |
+
GET /api/models/available
|
| 667 |
+
```
|
| 668 |
+
|
| 669 |
+
**Example:**
|
| 670 |
+
```bash
|
| 671 |
+
curl "http://localhost:7860/api/models/list"
|
| 672 |
+
```
|
| 673 |
+
|
| 674 |
+
---
|
| 675 |
+
|
| 676 |
+
### 8.2 Load AI Model
|
| 677 |
+
```bash
|
| 678 |
+
POST /hf/models/load
|
| 679 |
+
```
|
| 680 |
+
|
| 681 |
+
**Body:**
|
| 682 |
+
```json
|
| 683 |
+
{
|
| 684 |
+
"model_key": "cryptobert"
|
| 685 |
+
}
|
| 686 |
+
```
|
| 687 |
+
|
| 688 |
+
---
|
| 689 |
+
|
| 690 |
+
### 8.3 AI Price Prediction
|
| 691 |
+
```bash
|
| 692 |
+
GET /api/ai/predict/{symbol}
|
| 693 |
+
POST /api/ai/predict
|
| 694 |
+
```
|
| 695 |
+
|
| 696 |
+
---
|
| 697 |
+
|
| 698 |
+
### 8.4 Trading Signal
|
| 699 |
+
```bash
|
| 700 |
+
POST /api/trading/signal
|
| 701 |
+
```
|
| 702 |
+
|
| 703 |
+
**Body:**
|
| 704 |
+
```json
|
| 705 |
+
{
|
| 706 |
+
"symbol": "BTC",
|
| 707 |
+
"timeframe": "1h"
|
| 708 |
+
}
|
| 709 |
+
```
|
| 710 |
+
|
| 711 |
+
---
|
| 712 |
+
|
| 713 |
+
### 8.5 HuggingFace Datasets
|
| 714 |
+
```bash
|
| 715 |
+
GET /hf/datasets
|
| 716 |
+
GET /api/resources/hf/ohlcv?symbol=BTC&timeframe=1h
|
| 717 |
+
GET /api/resources/hf/symbols
|
| 718 |
+
```
|
| 719 |
+
|
| 720 |
+
**Example:**
|
| 721 |
+
```bash
|
| 722 |
+
curl "http://localhost:7860/api/resources/hf/symbols"
|
| 723 |
+
```
|
| 724 |
+
|
| 725 |
+
---
|
| 726 |
+
|
| 727 |
+
## 9. HuggingFace Space Crypto API
|
| 728 |
+
|
| 729 |
+
External API providing market data and 281 curated resources.
|
| 730 |
+
|
| 731 |
+
### 9.1 Market Data
|
| 732 |
+
```bash
|
| 733 |
+
GET /api/hf-space/coins/top?limit=50
|
| 734 |
+
GET /api/hf-space/trending
|
| 735 |
+
GET /api/hf-space/market
|
| 736 |
+
```
|
| 737 |
+
|
| 738 |
+
### 9.2 Sentiment
|
| 739 |
+
```bash
|
| 740 |
+
GET /api/hf-space/sentiment
|
| 741 |
+
GET /api/hf-space/sentiment/{symbol}
|
| 742 |
+
```
|
| 743 |
+
|
| 744 |
+
### 9.3 Resources Database (281 resources)
|
| 745 |
+
```bash
|
| 746 |
+
GET /api/hf-space/resources/stats
|
| 747 |
+
GET /api/hf-space/resources/categories
|
| 748 |
+
GET /api/hf-space/resources/category/{category}
|
| 749 |
+
GET /api/hf-space/resources/all
|
| 750 |
+
```
|
| 751 |
+
|
| 752 |
+
**Available Categories:**
|
| 753 |
+
- `rpc_nodes` (24)
|
| 754 |
+
- `block_explorers` (33)
|
| 755 |
+
- `market_data_apis` (33)
|
| 756 |
+
- `news_apis` (17)
|
| 757 |
+
- `sentiment_apis` (14)
|
| 758 |
+
- `onchain_analytics_apis` (14)
|
| 759 |
+
- `whale_tracking_apis` (10)
|
| 760 |
+
- `hf_resources` (9)
|
| 761 |
+
- `free_http_endpoints` (13)
|
| 762 |
+
- `cors_proxies` (7)
|
| 763 |
+
|
| 764 |
+
**Example:**
|
| 765 |
+
```bash
|
| 766 |
+
# Get all RPC nodes
|
| 767 |
+
curl "http://localhost:7860/api/hf-space/resources/category/rpc_nodes"
|
| 768 |
+
|
| 769 |
+
# Get all market data APIs
|
| 770 |
+
curl "http://localhost:7860/api/hf-space/resources/category/market_data_apis"
|
| 771 |
+
```
|
| 772 |
+
|
| 773 |
+
### 9.4 System Status
|
| 774 |
+
```bash
|
| 775 |
+
GET /api/hf-space/health
|
| 776 |
+
GET /api/hf-space/providers
|
| 777 |
+
GET /api/hf-space/status
|
| 778 |
+
```
|
| 779 |
+
|
| 780 |
+
---
|
| 781 |
+
|
| 782 |
+
## 10. System & Monitoring
|
| 783 |
+
|
| 784 |
+
### 10.1 Health Check
|
| 785 |
+
```bash
|
| 786 |
+
GET /health
|
| 787 |
+
GET /api/health
|
| 788 |
+
GET /api/multi-source/health
|
| 789 |
+
```
|
| 790 |
+
|
| 791 |
+
---
|
| 792 |
+
|
| 793 |
+
### 10.2 System Status
|
| 794 |
+
```bash
|
| 795 |
+
GET /api/status
|
| 796 |
+
GET /api/monitoring/status
|
| 797 |
+
```
|
| 798 |
+
|
| 799 |
+
---
|
| 800 |
+
|
| 801 |
+
### 10.3 Source Statistics
|
| 802 |
+
```bash
|
| 803 |
+
GET /api/multi-source/sources/status
|
| 804 |
+
GET /api/multi-source/monitoring/stats
|
| 805 |
+
GET /api/providers/stats
|
| 806 |
+
```
|
| 807 |
+
|
| 808 |
+
---
|
| 809 |
+
|
| 810 |
+
### 10.4 Background Worker
|
| 811 |
+
```bash
|
| 812 |
+
GET /api/worker/status
|
| 813 |
+
GET /api/worker/stats
|
| 814 |
+
POST /api/worker/start
|
| 815 |
+
POST /api/worker/stop
|
| 816 |
+
```
|
| 817 |
+
|
| 818 |
+
---
|
| 819 |
+
|
| 820 |
+
## Quick Reference Table
|
| 821 |
+
|
| 822 |
+
| Service | Endpoint | Method |
|
| 823 |
+
|---------|----------|--------|
|
| 824 |
+
| **Prices** | `/api/market/price?symbol=BTC` | GET |
|
| 825 |
+
| **Multi-Source Prices** | `/api/multi-source/prices` | GET |
|
| 826 |
+
| **Top Coins** | `/api/hf-space/coins/top` | GET |
|
| 827 |
+
| **Trending** | `/api/hf-space/trending` | GET |
|
| 828 |
+
| **Market Overview** | `/api/hf-space/market` | GET |
|
| 829 |
+
| **OHLCV** | `/api/multi-source/ohlc/{symbol}` | GET |
|
| 830 |
+
| **RSI** | `/api/indicators/rsi?symbol=BTC` | GET |
|
| 831 |
+
| **MACD** | `/api/indicators/macd?symbol=BTC` | GET |
|
| 832 |
+
| **Bollinger Bands** | `/api/indicators/bollinger-bands` | GET |
|
| 833 |
+
| **SMA** | `/api/indicators/sma?symbol=BTC` | GET |
|
| 834 |
+
| **EMA** | `/api/indicators/ema?symbol=BTC` | GET |
|
| 835 |
+
| **All Indicators** | `/api/indicators/comprehensive` | GET |
|
| 836 |
+
| **Fear & Greed** | `/api/hf-space/sentiment` | GET |
|
| 837 |
+
| **Sentiment Analysis** | `/api/sentiment/analyze` | POST |
|
| 838 |
+
| **News** | `/api/multi-source/news` | GET |
|
| 839 |
+
| **Gas Prices** | `/api/blockchain/gas` | GET |
|
| 840 |
+
| **Whales** | `/api/service/whales` | GET |
|
| 841 |
+
| **AI Models** | `/api/models/list` | GET |
|
| 842 |
+
| **Resources DB** | `/api/hf-space/resources/stats` | GET |
|
| 843 |
+
| **Health** | `/health` | GET |
|
| 844 |
+
|
| 845 |
+
---
|
| 846 |
+
|
| 847 |
+
## Python Usage Examples
|
| 848 |
+
|
| 849 |
+
```python
|
| 850 |
+
import requests
|
| 851 |
+
|
| 852 |
+
BASE_URL = "http://localhost:7860"
|
| 853 |
+
|
| 854 |
+
# Get BTC price
|
| 855 |
+
price = requests.get(f"{BASE_URL}/api/market/price?symbol=BTC").json()
|
| 856 |
+
print(f"BTC: ${price['price']:,.2f}")
|
| 857 |
+
|
| 858 |
+
# Get RSI
|
| 859 |
+
rsi = requests.get(f"{BASE_URL}/api/indicators/rsi?symbol=BTC&timeframe=1h").json()
|
| 860 |
+
print(f"RSI: {rsi['data']['value']}")
|
| 861 |
+
|
| 862 |
+
# Get comprehensive analysis
|
| 863 |
+
analysis = requests.get(f"{BASE_URL}/api/indicators/comprehensive?symbol=BTC").json()
|
| 864 |
+
print(f"Signal: {analysis['overall_signal']}")
|
| 865 |
+
|
| 866 |
+
# Get Fear & Greed
|
| 867 |
+
sentiment = requests.get(f"{BASE_URL}/api/hf-space/sentiment").json()
|
| 868 |
+
print(f"Fear & Greed: {sentiment['fear_greed_index']}")
|
| 869 |
+
|
| 870 |
+
# Analyze text sentiment
|
| 871 |
+
response = requests.post(
|
| 872 |
+
f"{BASE_URL}/api/sentiment/analyze",
|
| 873 |
+
json={"text": "Bitcoin is going to the moon!"}
|
| 874 |
+
)
|
| 875 |
+
print(f"Sentiment: {response.json()['sentiment']}")
|
| 876 |
+
|
| 877 |
+
# Get OHLCV candles
|
| 878 |
+
ohlcv = requests.get(f"{BASE_URL}/api/multi-source/ohlc/BTC?timeframe=1h&limit=100").json()
|
| 879 |
+
print(f"Candles: {len(ohlcv.get('data', []))}")
|
| 880 |
+
|
| 881 |
+
# Get news
|
| 882 |
+
news = requests.get(f"{BASE_URL}/api/multi-source/news?query=bitcoin&limit=10").json()
|
| 883 |
+
print(f"Articles: {len(news.get('articles', []))}")
|
| 884 |
+
```
|
| 885 |
+
|
| 886 |
+
---
|
| 887 |
+
|
| 888 |
+
*Last updated: 2025-12-12*
|
HF_SPACE_CRYPTO_API_GUIDE.md
ADDED
|
@@ -0,0 +1,666 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# HuggingFace Space Crypto Resources API - Client Guide
|
| 2 |
+
|
| 3 |
+
## راهنمای استفاده از API منابع کریپتو
|
| 4 |
+
|
| 5 |
+
**Base URL:** `https://really-amin-crypto-api-clean.hf.space`
|
| 6 |
+
**Local Proxy:** `http://localhost:7860/api/hf-space`
|
| 7 |
+
**Documentation:** https://really-amin-crypto-api-clean.hf.space/docs
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## 📋 Table of Contents
|
| 12 |
+
|
| 13 |
+
1. [Overview](#overview)
|
| 14 |
+
2. [Market Data Services](#1-market-data-services)
|
| 15 |
+
3. [Sentiment Services](#2-sentiment-services)
|
| 16 |
+
4. [Resources Database](#3-resources-database)
|
| 17 |
+
5. [System Status](#4-system-status)
|
| 18 |
+
6. [Python Client Usage](#5-python-client-usage)
|
| 19 |
+
7. [Response Format](#6-response-format)
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## Overview
|
| 24 |
+
|
| 25 |
+
This API provides:
|
| 26 |
+
- **Real-time market data** from CoinGecko
|
| 27 |
+
- **Sentiment analysis** (Fear & Greed Index) from Alternative.me
|
| 28 |
+
- **Resource database** with 281 crypto data sources across 12 categories
|
| 29 |
+
- **No authentication required** - All endpoints are public
|
| 30 |
+
- **Unlimited rate limit**
|
| 31 |
+
|
| 32 |
+
---
|
| 33 |
+
|
| 34 |
+
## 1. Market Data Services
|
| 35 |
+
|
| 36 |
+
### 1.1 Top Coins by Market Cap
|
| 37 |
+
|
| 38 |
+
Get the top cryptocurrencies ranked by market capitalization.
|
| 39 |
+
|
| 40 |
+
**Endpoint:**
|
| 41 |
+
```
|
| 42 |
+
GET /api/coins/top
|
| 43 |
+
GET /api/hf-space/coins/top (local proxy)
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
**Parameters:**
|
| 47 |
+
| Parameter | Type | Default | Description |
|
| 48 |
+
|-----------|------|---------|-------------|
|
| 49 |
+
| `limit` | integer | 50 | Number of coins (1-250) |
|
| 50 |
+
|
| 51 |
+
**Request:**
|
| 52 |
+
```bash
|
| 53 |
+
# Direct
|
| 54 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/coins/top?limit=10"
|
| 55 |
+
|
| 56 |
+
# Local Proxy
|
| 57 |
+
curl "http://localhost:7860/api/hf-space/coins/top?limit=10"
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
**Response:**
|
| 61 |
+
```json
|
| 62 |
+
{
|
| 63 |
+
"coins": [
|
| 64 |
+
{
|
| 65 |
+
"id": "bitcoin",
|
| 66 |
+
"symbol": "btc",
|
| 67 |
+
"name": "Bitcoin",
|
| 68 |
+
"image": "https://...",
|
| 69 |
+
"current_price": 90241.00,
|
| 70 |
+
"market_cap": 1800580721557,
|
| 71 |
+
"market_cap_rank": 1,
|
| 72 |
+
"total_volume": 69997758241,
|
| 73 |
+
"high_24h": 93468,
|
| 74 |
+
"low_24h": 89600,
|
| 75 |
+
"price_change_24h": -703.87,
|
| 76 |
+
"price_change_percentage_24h": -0.77,
|
| 77 |
+
"circulating_supply": 19961237.0,
|
| 78 |
+
"ath": 126080,
|
| 79 |
+
"ath_date": "2025-10-06T18:57:42.558Z",
|
| 80 |
+
"last_updated": "2025-12-12T19:22:00.626Z"
|
| 81 |
+
}
|
| 82 |
+
],
|
| 83 |
+
"total": 10,
|
| 84 |
+
"timestamp": "2025-12-12T19:22:43.023917Z"
|
| 85 |
+
}
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
---
|
| 89 |
+
|
| 90 |
+
### 1.2 Trending Coins
|
| 91 |
+
|
| 92 |
+
Get currently trending cryptocurrencies.
|
| 93 |
+
|
| 94 |
+
**Endpoint:**
|
| 95 |
+
```
|
| 96 |
+
GET /api/trending
|
| 97 |
+
GET /api/hf-space/trending (local proxy)
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
**Request:**
|
| 101 |
+
```bash
|
| 102 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/trending"
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
**Response:**
|
| 106 |
+
```json
|
| 107 |
+
{
|
| 108 |
+
"coins": [
|
| 109 |
+
{
|
| 110 |
+
"id": "gala",
|
| 111 |
+
"name": "GALA",
|
| 112 |
+
"symbol": "GALA",
|
| 113 |
+
"market_cap_rank": 206,
|
| 114 |
+
"thumb": "https://...",
|
| 115 |
+
"price_btc": 7.758989661597377e-08
|
| 116 |
+
}
|
| 117 |
+
],
|
| 118 |
+
"total": 10,
|
| 119 |
+
"timestamp": "2025-12-12T19:22:49.419456Z"
|
| 120 |
+
}
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
---
|
| 124 |
+
|
| 125 |
+
### 1.3 Global Market Overview
|
| 126 |
+
|
| 127 |
+
Get global cryptocurrency market statistics.
|
| 128 |
+
|
| 129 |
+
**Endpoint:**
|
| 130 |
+
```
|
| 131 |
+
GET /api/market
|
| 132 |
+
GET /api/hf-space/market (local proxy)
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
**Request:**
|
| 136 |
+
```bash
|
| 137 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/market"
|
| 138 |
+
```
|
| 139 |
+
|
| 140 |
+
**Response:**
|
| 141 |
+
```json
|
| 142 |
+
{
|
| 143 |
+
"total_market_cap": 3152683901788.04,
|
| 144 |
+
"total_volume": 148435101985.29,
|
| 145 |
+
"market_cap_percentage": {
|
| 146 |
+
"btc": 57.09,
|
| 147 |
+
"eth": 11.77,
|
| 148 |
+
"usdt": 5.91,
|
| 149 |
+
"xrp": 3.85,
|
| 150 |
+
"bnb": 3.84
|
| 151 |
+
},
|
| 152 |
+
"market_cap_change_percentage_24h": -1.06,
|
| 153 |
+
"active_cryptocurrencies": 19190,
|
| 154 |
+
"markets": 1440,
|
| 155 |
+
"timestamp": "2025-12-12T19:22:50.922474Z"
|
| 156 |
+
}
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## 2. Sentiment Services
|
| 162 |
+
|
| 163 |
+
### 2.1 Global Sentiment (Fear & Greed Index)
|
| 164 |
+
|
| 165 |
+
Get the current Fear & Greed Index.
|
| 166 |
+
|
| 167 |
+
**Endpoint:**
|
| 168 |
+
```
|
| 169 |
+
GET /api/sentiment/global
|
| 170 |
+
GET /api/hf-space/sentiment (local proxy)
|
| 171 |
+
```
|
| 172 |
+
|
| 173 |
+
**Parameters:**
|
| 174 |
+
| Parameter | Type | Default | Description |
|
| 175 |
+
|-----------|------|---------|-------------|
|
| 176 |
+
| `timeframe` | string | "1D" | Timeframe for data |
|
| 177 |
+
|
| 178 |
+
**Request:**
|
| 179 |
+
```bash
|
| 180 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/sentiment/global"
|
| 181 |
+
```
|
| 182 |
+
|
| 183 |
+
**Response:**
|
| 184 |
+
```json
|
| 185 |
+
{
|
| 186 |
+
"fear_greed_index": 29,
|
| 187 |
+
"sentiment": "fear",
|
| 188 |
+
"market_mood": "bearish",
|
| 189 |
+
"confidence": 0.85,
|
| 190 |
+
"history": [
|
| 191 |
+
{
|
| 192 |
+
"timestamp": 1765497600000,
|
| 193 |
+
"sentiment": 29,
|
| 194 |
+
"classification": "Fear"
|
| 195 |
+
}
|
| 196 |
+
],
|
| 197 |
+
"timestamp": "2025-12-12T19:22:52.215750Z",
|
| 198 |
+
"source": "alternative.me"
|
| 199 |
+
}
|
| 200 |
+
```
|
| 201 |
+
|
| 202 |
+
**Index Classification:**
|
| 203 |
+
| Range | Classification |
|
| 204 |
+
|-------|----------------|
|
| 205 |
+
| 0-24 | Extreme Fear |
|
| 206 |
+
| 25-49 | Fear |
|
| 207 |
+
| 50-74 | Greed |
|
| 208 |
+
| 75-100 | Extreme Greed |
|
| 209 |
+
|
| 210 |
+
---
|
| 211 |
+
|
| 212 |
+
### 2.2 Asset-Specific Sentiment
|
| 213 |
+
|
| 214 |
+
Get sentiment for a specific cryptocurrency.
|
| 215 |
+
|
| 216 |
+
**Endpoint:**
|
| 217 |
+
```
|
| 218 |
+
GET /api/sentiment/asset/{symbol}
|
| 219 |
+
GET /api/hf-space/sentiment/{symbol} (local proxy)
|
| 220 |
+
```
|
| 221 |
+
|
| 222 |
+
**Request:**
|
| 223 |
+
```bash
|
| 224 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/sentiment/asset/BTC"
|
| 225 |
+
```
|
| 226 |
+
|
| 227 |
+
**Response:**
|
| 228 |
+
```json
|
| 229 |
+
{
|
| 230 |
+
"symbol": "BTC",
|
| 231 |
+
"sentiment": "neutral",
|
| 232 |
+
"score": 50,
|
| 233 |
+
"confidence": 0.5,
|
| 234 |
+
"timestamp": "2025-12-12T19:22:53.614869Z"
|
| 235 |
+
}
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
---
|
| 239 |
+
|
| 240 |
+
## 3. Resources Database
|
| 241 |
+
|
| 242 |
+
The API provides access to a curated database of **281 crypto data resources** across **12 categories**.
|
| 243 |
+
|
| 244 |
+
### 3.1 Get Resources Statistics
|
| 245 |
+
|
| 246 |
+
**Endpoint:**
|
| 247 |
+
```
|
| 248 |
+
GET /api/resources/stats
|
| 249 |
+
GET /api/hf-space/resources/stats (local proxy)
|
| 250 |
+
```
|
| 251 |
+
|
| 252 |
+
**Request:**
|
| 253 |
+
```bash
|
| 254 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/resources/stats"
|
| 255 |
+
```
|
| 256 |
+
|
| 257 |
+
**Response:**
|
| 258 |
+
```json
|
| 259 |
+
{
|
| 260 |
+
"total_resources": 281,
|
| 261 |
+
"total_categories": 12,
|
| 262 |
+
"categories": {
|
| 263 |
+
"rpc_nodes": 24,
|
| 264 |
+
"block_explorers": 33,
|
| 265 |
+
"market_data_apis": 33,
|
| 266 |
+
"news_apis": 17,
|
| 267 |
+
"sentiment_apis": 14,
|
| 268 |
+
"onchain_analytics_apis": 14,
|
| 269 |
+
"whale_tracking_apis": 10,
|
| 270 |
+
"community_sentiment_apis": 1,
|
| 271 |
+
"hf_resources": 9,
|
| 272 |
+
"free_http_endpoints": 13,
|
| 273 |
+
"local_backend_routes": 106,
|
| 274 |
+
"cors_proxies": 7
|
| 275 |
+
},
|
| 276 |
+
"metadata": {
|
| 277 |
+
"version": "1.0",
|
| 278 |
+
"updated": "2025-12-08"
|
| 279 |
+
}
|
| 280 |
+
}
|
| 281 |
+
```
|
| 282 |
+
|
| 283 |
+
---
|
| 284 |
+
|
| 285 |
+
### 3.2 List All Categories
|
| 286 |
+
|
| 287 |
+
**Endpoint:**
|
| 288 |
+
```
|
| 289 |
+
GET /api/categories
|
| 290 |
+
GET /api/hf-space/resources/categories (local proxy)
|
| 291 |
+
```
|
| 292 |
+
|
| 293 |
+
**Request:**
|
| 294 |
+
```bash
|
| 295 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/categories"
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
**Response:**
|
| 299 |
+
```json
|
| 300 |
+
{
|
| 301 |
+
"total": 12,
|
| 302 |
+
"categories": [
|
| 303 |
+
{
|
| 304 |
+
"name": "rpc_nodes",
|
| 305 |
+
"count": 24,
|
| 306 |
+
"endpoint": "/api/resources/category/rpc_nodes"
|
| 307 |
+
},
|
| 308 |
+
{
|
| 309 |
+
"name": "market_data_apis",
|
| 310 |
+
"count": 33,
|
| 311 |
+
"endpoint": "/api/resources/category/market_data_apis"
|
| 312 |
+
}
|
| 313 |
+
]
|
| 314 |
+
}
|
| 315 |
+
```
|
| 316 |
+
|
| 317 |
+
---
|
| 318 |
+
|
| 319 |
+
### 3.3 Get Resources by Category
|
| 320 |
+
|
| 321 |
+
**Endpoint:**
|
| 322 |
+
```
|
| 323 |
+
GET /api/resources/category/{category}
|
| 324 |
+
GET /api/hf-space/resources/category/{category} (local proxy)
|
| 325 |
+
```
|
| 326 |
+
|
| 327 |
+
**Available Categories:**
|
| 328 |
+
|
| 329 |
+
| Category | Count | Description |
|
| 330 |
+
|----------|-------|-------------|
|
| 331 |
+
| `rpc_nodes` | 24 | Ethereum, BSC, Polygon RPC endpoints |
|
| 332 |
+
| `block_explorers` | 33 | Etherscan, BSCScan, Polygonscan, etc. |
|
| 333 |
+
| `market_data_apis` | 33 | CoinGecko, CoinMarketCap, Binance, etc. |
|
| 334 |
+
| `news_apis` | 17 | Crypto news sources |
|
| 335 |
+
| `sentiment_apis` | 14 | LunarCrush, Santiment, Alternative.me |
|
| 336 |
+
| `onchain_analytics_apis` | 14 | Glassnode, CryptoQuant, Nansen |
|
| 337 |
+
| `whale_tracking_apis` | 10 | Whale Alert, Arkham, DeBank |
|
| 338 |
+
| `hf_resources` | 9 | HuggingFace models & datasets |
|
| 339 |
+
| `free_http_endpoints` | 13 | Free API endpoints |
|
| 340 |
+
| `local_backend_routes` | 106 | Local backend routes |
|
| 341 |
+
| `cors_proxies` | 7 | CORS proxy services |
|
| 342 |
+
| `community_sentiment_apis` | 1 | Community sentiment |
|
| 343 |
+
|
| 344 |
+
**Request:**
|
| 345 |
+
```bash
|
| 346 |
+
# Get all RPC nodes
|
| 347 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/resources/category/rpc_nodes"
|
| 348 |
+
|
| 349 |
+
# Get all market data APIs
|
| 350 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/resources/category/market_data_apis"
|
| 351 |
+
|
| 352 |
+
# Get whale tracking APIs
|
| 353 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/resources/category/whale_tracking_apis"
|
| 354 |
+
```
|
| 355 |
+
|
| 356 |
+
**Response (example: rpc_nodes):**
|
| 357 |
+
```json
|
| 358 |
+
{
|
| 359 |
+
"category": "rpc_nodes",
|
| 360 |
+
"total": 24,
|
| 361 |
+
"resources": [
|
| 362 |
+
{
|
| 363 |
+
"id": "publicnode_eth_mainnet",
|
| 364 |
+
"name": "PublicNode Ethereum",
|
| 365 |
+
"chain": "ethereum",
|
| 366 |
+
"role": "rpc",
|
| 367 |
+
"base_url": "https://ethereum.publicnode.com",
|
| 368 |
+
"auth": {
|
| 369 |
+
"type": "none"
|
| 370 |
+
},
|
| 371 |
+
"docs_url": "https://www.publicnode.com",
|
| 372 |
+
"notes": "Free, no rate limit"
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"id": "infura_eth_mainnet",
|
| 376 |
+
"name": "Infura Ethereum Mainnet",
|
| 377 |
+
"chain": "ethereum",
|
| 378 |
+
"base_url": "https://mainnet.infura.io/v3/{PROJECT_ID}",
|
| 379 |
+
"auth": {
|
| 380 |
+
"type": "apiKeyPath",
|
| 381 |
+
"param_name": "PROJECT_ID"
|
| 382 |
+
},
|
| 383 |
+
"docs_url": "https://docs.infura.io",
|
| 384 |
+
"notes": "Free tier: 100K req/day"
|
| 385 |
+
}
|
| 386 |
+
]
|
| 387 |
+
}
|
| 388 |
+
```
|
| 389 |
+
|
| 390 |
+
**Response (example: market_data_apis):**
|
| 391 |
+
```json
|
| 392 |
+
{
|
| 393 |
+
"category": "market_data_apis",
|
| 394 |
+
"total": 33,
|
| 395 |
+
"resources": [
|
| 396 |
+
{
|
| 397 |
+
"id": "coingecko",
|
| 398 |
+
"name": "CoinGecko",
|
| 399 |
+
"role": "primary_free",
|
| 400 |
+
"base_url": "https://api.coingecko.com/api/v3",
|
| 401 |
+
"auth": { "type": "none" },
|
| 402 |
+
"docs_url": "https://www.coingecko.com/en/api/documentation",
|
| 403 |
+
"endpoints": {
|
| 404 |
+
"simple_price": "/simple/price?ids={ids}&vs_currencies={fiats}",
|
| 405 |
+
"coin_data": "/coins/{id}?localization=false",
|
| 406 |
+
"market_chart": "/coins/{id}/market_chart?vs_currency=usd&days=7",
|
| 407 |
+
"global_data": "/global",
|
| 408 |
+
"trending": "/search/trending"
|
| 409 |
+
},
|
| 410 |
+
"notes": "Rate limit: 10-50 calls/min (free)"
|
| 411 |
+
}
|
| 412 |
+
]
|
| 413 |
+
}
|
| 414 |
+
```
|
| 415 |
+
|
| 416 |
+
---
|
| 417 |
+
|
| 418 |
+
### 3.4 Get All Resources
|
| 419 |
+
|
| 420 |
+
**Endpoint:**
|
| 421 |
+
```
|
| 422 |
+
GET /api/resources/list
|
| 423 |
+
GET /api/hf-space/resources/all (local proxy)
|
| 424 |
+
```
|
| 425 |
+
|
| 426 |
+
**Request:**
|
| 427 |
+
```bash
|
| 428 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/resources/list"
|
| 429 |
+
```
|
| 430 |
+
|
| 431 |
+
---
|
| 432 |
+
|
| 433 |
+
## 4. System Status
|
| 434 |
+
|
| 435 |
+
### 4.1 Health Check
|
| 436 |
+
|
| 437 |
+
**Endpoint:**
|
| 438 |
+
```
|
| 439 |
+
GET /health
|
| 440 |
+
GET /api/hf-space/health (local proxy)
|
| 441 |
+
```
|
| 442 |
+
|
| 443 |
+
**Request:**
|
| 444 |
+
```bash
|
| 445 |
+
curl "https://really-amin-crypto-api-clean.hf.space/health"
|
| 446 |
+
```
|
| 447 |
+
|
| 448 |
+
**Response:**
|
| 449 |
+
```json
|
| 450 |
+
{
|
| 451 |
+
"status": "healthy",
|
| 452 |
+
"timestamp": "2025-12-12T19:22:38.977664",
|
| 453 |
+
"resources_loaded": true,
|
| 454 |
+
"total_categories": 12,
|
| 455 |
+
"websocket_connections": 0
|
| 456 |
+
}
|
| 457 |
+
```
|
| 458 |
+
|
| 459 |
+
---
|
| 460 |
+
|
| 461 |
+
### 4.2 Data Providers Status
|
| 462 |
+
|
| 463 |
+
**Endpoint:**
|
| 464 |
+
```
|
| 465 |
+
GET /api/providers
|
| 466 |
+
GET /api/hf-space/providers (local proxy)
|
| 467 |
+
```
|
| 468 |
+
|
| 469 |
+
**Request:**
|
| 470 |
+
```bash
|
| 471 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/providers"
|
| 472 |
+
```
|
| 473 |
+
|
| 474 |
+
**Response:**
|
| 475 |
+
```json
|
| 476 |
+
{
|
| 477 |
+
"providers": [
|
| 478 |
+
{
|
| 479 |
+
"name": "CoinGecko",
|
| 480 |
+
"status": "active",
|
| 481 |
+
"endpoint": "https://api.coingecko.com",
|
| 482 |
+
"latency": 148,
|
| 483 |
+
"success_rate": 97
|
| 484 |
+
},
|
| 485 |
+
{
|
| 486 |
+
"name": "Binance",
|
| 487 |
+
"status": "active",
|
| 488 |
+
"endpoint": "https://api.binance.com",
|
| 489 |
+
"latency": 72,
|
| 490 |
+
"success_rate": 96
|
| 491 |
+
}
|
| 492 |
+
],
|
| 493 |
+
"total": 3
|
| 494 |
+
}
|
| 495 |
+
```
|
| 496 |
+
|
| 497 |
+
---
|
| 498 |
+
|
| 499 |
+
### 4.3 System Status
|
| 500 |
+
|
| 501 |
+
**Endpoint:**
|
| 502 |
+
```
|
| 503 |
+
GET /api/status
|
| 504 |
+
GET /api/hf-space/status (local proxy)
|
| 505 |
+
```
|
| 506 |
+
|
| 507 |
+
**Request:**
|
| 508 |
+
```bash
|
| 509 |
+
curl "https://really-amin-crypto-api-clean.hf.space/api/status"
|
| 510 |
+
```
|
| 511 |
+
|
| 512 |
+
**Response:**
|
| 513 |
+
```json
|
| 514 |
+
{
|
| 515 |
+
"status": "online",
|
| 516 |
+
"health": "healthy",
|
| 517 |
+
"avg_response_time": 83,
|
| 518 |
+
"cache_hit_rate": 76,
|
| 519 |
+
"active_connections": 6,
|
| 520 |
+
"uptime": "99.9%"
|
| 521 |
+
}
|
| 522 |
+
```
|
| 523 |
+
|
| 524 |
+
---
|
| 525 |
+
|
| 526 |
+
## 5. Python Client Usage
|
| 527 |
+
|
| 528 |
+
### 5.1 Using the Service (Async)
|
| 529 |
+
|
| 530 |
+
```python
|
| 531 |
+
from backend.services.hf_space_crypto_client import get_hf_space_crypto_service
|
| 532 |
+
import asyncio
|
| 533 |
+
|
| 534 |
+
async def main():
|
| 535 |
+
service = get_hf_space_crypto_service()
|
| 536 |
+
|
| 537 |
+
# Get top 10 coins
|
| 538 |
+
result = await service.get_top_coins(limit=10)
|
| 539 |
+
if result["success"]:
|
| 540 |
+
for coin in result["data"]["coins"]:
|
| 541 |
+
print(f"{coin['name']}: ${coin['current_price']:,.2f}")
|
| 542 |
+
|
| 543 |
+
# Get Fear & Greed Index
|
| 544 |
+
fgi = await service.get_fear_greed_index()
|
| 545 |
+
print(f"Fear & Greed Index: {fgi}")
|
| 546 |
+
|
| 547 |
+
# Get market overview
|
| 548 |
+
result = await service.get_market_overview()
|
| 549 |
+
if result["success"]:
|
| 550 |
+
print(f"Total Market Cap: ${result['data']['total_market_cap']:,.0f}")
|
| 551 |
+
|
| 552 |
+
# Get resources by category
|
| 553 |
+
result = await service.get_resources_by_category("market_data_apis")
|
| 554 |
+
if result["success"]:
|
| 555 |
+
for resource in result["data"]["resources"][:5]:
|
| 556 |
+
print(f"- {resource['name']}: {resource['base_url']}")
|
| 557 |
+
|
| 558 |
+
await service.close()
|
| 559 |
+
|
| 560 |
+
asyncio.run(main())
|
| 561 |
+
```
|
| 562 |
+
|
| 563 |
+
### 5.2 Using the Standalone Client (Sync/Async)
|
| 564 |
+
|
| 565 |
+
```python
|
| 566 |
+
from collectors.hf_crypto_api_client import HFCryptoAPIClient
|
| 567 |
+
|
| 568 |
+
# Synchronous usage
|
| 569 |
+
client = HFCryptoAPIClient()
|
| 570 |
+
|
| 571 |
+
# Get top coins
|
| 572 |
+
coins = client.get_top_coins(limit=10)
|
| 573 |
+
for coin in coins.get("coins", []):
|
| 574 |
+
print(f"{coin['name']}: ${coin['current_price']:,.2f}")
|
| 575 |
+
|
| 576 |
+
# Get Fear & Greed Index
|
| 577 |
+
fgi = client.get_fear_greed_index()
|
| 578 |
+
print(f"Fear & Greed: {fgi}")
|
| 579 |
+
|
| 580 |
+
# Get BTC price
|
| 581 |
+
btc_price = client.get_btc_price()
|
| 582 |
+
print(f"BTC: ${btc_price:,.2f}")
|
| 583 |
+
|
| 584 |
+
# Get total market cap
|
| 585 |
+
mcap = client.get_total_market_cap()
|
| 586 |
+
print(f"Market Cap: ${mcap:,.0f}")
|
| 587 |
+
|
| 588 |
+
# Get RPC nodes
|
| 589 |
+
rpc_nodes = client.get_rpc_nodes()
|
| 590 |
+
for node in rpc_nodes[:5]:
|
| 591 |
+
print(f"- {node['name']}: {node['base_url']}")
|
| 592 |
+
|
| 593 |
+
# Get market data APIs
|
| 594 |
+
apis = client.get_market_data_apis()
|
| 595 |
+
for api in apis[:5]:
|
| 596 |
+
print(f"- {api['name']}: {api['base_url']}")
|
| 597 |
+
```
|
| 598 |
+
|
| 599 |
+
### 5.3 Using from Collectors Package
|
| 600 |
+
|
| 601 |
+
```python
|
| 602 |
+
from collectors import HFCryptoAPIClient, get_hf_crypto_client
|
| 603 |
+
|
| 604 |
+
# Get singleton client
|
| 605 |
+
client = get_hf_crypto_client()
|
| 606 |
+
|
| 607 |
+
# Use the client
|
| 608 |
+
coins = client.get_top_coins(limit=5)
|
| 609 |
+
sentiment = client.get_global_sentiment()
|
| 610 |
+
resources = client.get_resources_stats()
|
| 611 |
+
```
|
| 612 |
+
|
| 613 |
+
---
|
| 614 |
+
|
| 615 |
+
## 6. Response Format
|
| 616 |
+
|
| 617 |
+
All endpoints return JSON with consistent structure:
|
| 618 |
+
|
| 619 |
+
### Success Response
|
| 620 |
+
```json
|
| 621 |
+
{
|
| 622 |
+
"data": { ... },
|
| 623 |
+
"total": 10,
|
| 624 |
+
"timestamp": "2025-12-12T19:22:43.023917Z"
|
| 625 |
+
}
|
| 626 |
+
```
|
| 627 |
+
|
| 628 |
+
### Error Response (via local proxy)
|
| 629 |
+
```json
|
| 630 |
+
{
|
| 631 |
+
"detail": "HF Space API unavailable: Request timeout"
|
| 632 |
+
}
|
| 633 |
+
```
|
| 634 |
+
|
| 635 |
+
---
|
| 636 |
+
|
| 637 |
+
## Quick Reference
|
| 638 |
+
|
| 639 |
+
| Service | Endpoint | Description |
|
| 640 |
+
|---------|----------|-------------|
|
| 641 |
+
| Top Coins | `GET /api/coins/top?limit=N` | Top N coins by market cap |
|
| 642 |
+
| Trending | `GET /api/trending` | Trending coins |
|
| 643 |
+
| Market | `GET /api/market` | Global market overview |
|
| 644 |
+
| Sentiment | `GET /api/sentiment/global` | Fear & Greed Index |
|
| 645 |
+
| Asset Sentiment | `GET /api/sentiment/asset/{symbol}` | Asset-specific sentiment |
|
| 646 |
+
| Resources Stats | `GET /api/resources/stats` | Database statistics |
|
| 647 |
+
| Categories | `GET /api/categories` | List all categories |
|
| 648 |
+
| By Category | `GET /api/resources/category/{cat}` | Resources in category |
|
| 649 |
+
| All Resources | `GET /api/resources/list` | All 281 resources |
|
| 650 |
+
| Health | `GET /health` | API health check |
|
| 651 |
+
| Providers | `GET /api/providers` | Data providers status |
|
| 652 |
+
| Status | `GET /api/status` | System status |
|
| 653 |
+
|
| 654 |
+
---
|
| 655 |
+
|
| 656 |
+
## Notes
|
| 657 |
+
|
| 658 |
+
- **No API key required** - All endpoints are public
|
| 659 |
+
- **Rate limit** - Unlimited (but be respectful)
|
| 660 |
+
- **Data freshness** - Market data updates every few seconds
|
| 661 |
+
- **Resources database** - Updated periodically, contains API keys for some services
|
| 662 |
+
- **WebSocket** - Available at `wss://really-amin-crypto-api-clean.hf.space/ws` for real-time updates
|
| 663 |
+
|
| 664 |
+
---
|
| 665 |
+
|
| 666 |
+
*Last updated: 2025-12-12*
|
backend/routers/hf_space_crypto_api.py
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Space Crypto Resources API Router
|
| 4 |
+
روتر API برای دسترسی به منابع کریپتو در HuggingFace Space
|
| 5 |
+
|
| 6 |
+
This router provides endpoints to access the external HF Space Crypto API:
|
| 7 |
+
https://really-amin-crypto-api-clean.hf.space
|
| 8 |
+
|
| 9 |
+
Endpoints:
|
| 10 |
+
- /api/hf-space/coins/top - Top coins by market cap
|
| 11 |
+
- /api/hf-space/trending - Trending coins
|
| 12 |
+
- /api/hf-space/market - Market overview
|
| 13 |
+
- /api/hf-space/sentiment - Fear & Greed Index
|
| 14 |
+
- /api/hf-space/resources - Resource database
|
| 15 |
+
"""
|
| 16 |
+
|
| 17 |
+
from fastapi import APIRouter, Query, HTTPException, Path
|
| 18 |
+
from typing import Optional, List
|
| 19 |
+
import logging
|
| 20 |
+
|
| 21 |
+
from backend.services.hf_space_crypto_client import get_hf_space_crypto_service
|
| 22 |
+
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
+
router = APIRouter(
|
| 26 |
+
prefix="/api/hf-space",
|
| 27 |
+
tags=["HuggingFace Space Crypto API"]
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
# ===== MARKET DATA ENDPOINTS =====
|
| 32 |
+
|
| 33 |
+
@router.get("/coins/top")
|
| 34 |
+
async def get_top_coins(
|
| 35 |
+
limit: int = Query(50, ge=1, le=250, description="Number of coins to return")
|
| 36 |
+
):
|
| 37 |
+
"""
|
| 38 |
+
Get top coins by market cap from HF Space API
|
| 39 |
+
|
| 40 |
+
دریافت برترین ارزها بر اساس مارکت کپ
|
| 41 |
+
|
| 42 |
+
Source: HuggingFace Space Crypto API → CoinGecko
|
| 43 |
+
|
| 44 |
+
Returns:
|
| 45 |
+
- coins: List of top coins with price, market cap, volume, etc.
|
| 46 |
+
- total: Total number of coins returned
|
| 47 |
+
- timestamp: Data timestamp
|
| 48 |
+
"""
|
| 49 |
+
try:
|
| 50 |
+
service = get_hf_space_crypto_service()
|
| 51 |
+
result = await service.get_top_coins(limit=limit)
|
| 52 |
+
|
| 53 |
+
if not result["success"]:
|
| 54 |
+
raise HTTPException(
|
| 55 |
+
status_code=503,
|
| 56 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
return result["data"]
|
| 60 |
+
|
| 61 |
+
except HTTPException:
|
| 62 |
+
raise
|
| 63 |
+
except Exception as e:
|
| 64 |
+
logger.error(f"❌ Top coins endpoint failed: {e}")
|
| 65 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
@router.get("/trending")
|
| 69 |
+
async def get_trending_coins():
|
| 70 |
+
"""
|
| 71 |
+
Get trending coins from HF Space API
|
| 72 |
+
|
| 73 |
+
دریافت ارزهای ترند
|
| 74 |
+
|
| 75 |
+
Source: HuggingFace Space Crypto API → CoinGecko
|
| 76 |
+
|
| 77 |
+
Returns:
|
| 78 |
+
- coins: List of trending coins
|
| 79 |
+
- total: Total number of trending coins
|
| 80 |
+
- timestamp: Data timestamp
|
| 81 |
+
"""
|
| 82 |
+
try:
|
| 83 |
+
service = get_hf_space_crypto_service()
|
| 84 |
+
result = await service.get_trending()
|
| 85 |
+
|
| 86 |
+
if not result["success"]:
|
| 87 |
+
raise HTTPException(
|
| 88 |
+
status_code=503,
|
| 89 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 90 |
+
)
|
| 91 |
+
|
| 92 |
+
return result["data"]
|
| 93 |
+
|
| 94 |
+
except HTTPException:
|
| 95 |
+
raise
|
| 96 |
+
except Exception as e:
|
| 97 |
+
logger.error(f"❌ Trending coins endpoint failed: {e}")
|
| 98 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
@router.get("/market")
|
| 102 |
+
async def get_market_overview():
|
| 103 |
+
"""
|
| 104 |
+
Get global market overview from HF Space API
|
| 105 |
+
|
| 106 |
+
خلاصه کلی بازار
|
| 107 |
+
|
| 108 |
+
Source: HuggingFace Space Crypto API → CoinGecko
|
| 109 |
+
|
| 110 |
+
Returns:
|
| 111 |
+
- total_market_cap: Total market cap in USD
|
| 112 |
+
- total_volume: 24h trading volume
|
| 113 |
+
- market_cap_percentage: Dominance by coin (BTC, ETH, etc.)
|
| 114 |
+
- active_cryptocurrencies: Number of active cryptos
|
| 115 |
+
- markets: Number of markets
|
| 116 |
+
"""
|
| 117 |
+
try:
|
| 118 |
+
service = get_hf_space_crypto_service()
|
| 119 |
+
result = await service.get_market_overview()
|
| 120 |
+
|
| 121 |
+
if not result["success"]:
|
| 122 |
+
raise HTTPException(
|
| 123 |
+
status_code=503,
|
| 124 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 125 |
+
)
|
| 126 |
+
|
| 127 |
+
return result["data"]
|
| 128 |
+
|
| 129 |
+
except HTTPException:
|
| 130 |
+
raise
|
| 131 |
+
except Exception as e:
|
| 132 |
+
logger.error(f"❌ Market overview endpoint failed: {e}")
|
| 133 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
# ===== SENTIMENT ENDPOINTS =====
|
| 137 |
+
|
| 138 |
+
@router.get("/sentiment")
|
| 139 |
+
async def get_global_sentiment(
|
| 140 |
+
timeframe: str = Query("1D", description="Timeframe for sentiment data")
|
| 141 |
+
):
|
| 142 |
+
"""
|
| 143 |
+
Get Fear & Greed Index from HF Space API
|
| 144 |
+
|
| 145 |
+
شاخص ترس و طمع
|
| 146 |
+
|
| 147 |
+
Source: HuggingFace Space Crypto API → Alternative.me
|
| 148 |
+
|
| 149 |
+
Returns:
|
| 150 |
+
- fear_greed_index: Current index value (0-100)
|
| 151 |
+
- sentiment: Classification (fear, greed, etc.)
|
| 152 |
+
- market_mood: Market mood (bearish, bullish, neutral)
|
| 153 |
+
- confidence: Confidence score
|
| 154 |
+
- source: Data source (alternative.me)
|
| 155 |
+
"""
|
| 156 |
+
try:
|
| 157 |
+
service = get_hf_space_crypto_service()
|
| 158 |
+
result = await service.get_global_sentiment(timeframe=timeframe)
|
| 159 |
+
|
| 160 |
+
if not result["success"]:
|
| 161 |
+
raise HTTPException(
|
| 162 |
+
status_code=503,
|
| 163 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 164 |
+
)
|
| 165 |
+
|
| 166 |
+
return result["data"]
|
| 167 |
+
|
| 168 |
+
except HTTPException:
|
| 169 |
+
raise
|
| 170 |
+
except Exception as e:
|
| 171 |
+
logger.error(f"❌ Sentiment endpoint failed: {e}")
|
| 172 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
@router.get("/sentiment/{symbol}")
|
| 176 |
+
async def get_asset_sentiment(
|
| 177 |
+
symbol: str = Path(..., description="Asset symbol (e.g., BTC, ETH)")
|
| 178 |
+
):
|
| 179 |
+
"""
|
| 180 |
+
Get sentiment for specific asset from HF Space API
|
| 181 |
+
|
| 182 |
+
احساسات یک ارز خاص
|
| 183 |
+
|
| 184 |
+
Returns:
|
| 185 |
+
- symbol: Asset symbol
|
| 186 |
+
- sentiment: Sentiment classification
|
| 187 |
+
- score: Sentiment score
|
| 188 |
+
- confidence: Confidence score
|
| 189 |
+
"""
|
| 190 |
+
try:
|
| 191 |
+
service = get_hf_space_crypto_service()
|
| 192 |
+
result = await service.get_asset_sentiment(symbol.upper())
|
| 193 |
+
|
| 194 |
+
if not result["success"]:
|
| 195 |
+
raise HTTPException(
|
| 196 |
+
status_code=503,
|
| 197 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
return result["data"]
|
| 201 |
+
|
| 202 |
+
except HTTPException:
|
| 203 |
+
raise
|
| 204 |
+
except Exception as e:
|
| 205 |
+
logger.error(f"❌ Asset sentiment endpoint failed: {e}")
|
| 206 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
# ===== RESOURCES DATABASE ENDPOINTS =====
|
| 210 |
+
|
| 211 |
+
@router.get("/resources/stats")
|
| 212 |
+
async def get_resources_stats():
|
| 213 |
+
"""
|
| 214 |
+
Get resources database statistics from HF Space API
|
| 215 |
+
|
| 216 |
+
آمار منابع
|
| 217 |
+
|
| 218 |
+
Returns:
|
| 219 |
+
- total_resources: Total number of resources (281)
|
| 220 |
+
- total_categories: Number of categories (12)
|
| 221 |
+
- categories: Resource count per category
|
| 222 |
+
- metadata: Database metadata
|
| 223 |
+
"""
|
| 224 |
+
try:
|
| 225 |
+
service = get_hf_space_crypto_service()
|
| 226 |
+
result = await service.get_resources_stats()
|
| 227 |
+
|
| 228 |
+
if not result["success"]:
|
| 229 |
+
raise HTTPException(
|
| 230 |
+
status_code=503,
|
| 231 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
return result["data"]
|
| 235 |
+
|
| 236 |
+
except HTTPException:
|
| 237 |
+
raise
|
| 238 |
+
except Exception as e:
|
| 239 |
+
logger.error(f"❌ Resources stats endpoint failed: {e}")
|
| 240 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
@router.get("/resources/categories")
|
| 244 |
+
async def get_categories():
|
| 245 |
+
"""
|
| 246 |
+
Get list of resource categories from HF Space API
|
| 247 |
+
|
| 248 |
+
لیست دستهبندیها
|
| 249 |
+
|
| 250 |
+
Returns:
|
| 251 |
+
- total: Number of categories
|
| 252 |
+
- categories: List of categories with name, count, and endpoint
|
| 253 |
+
"""
|
| 254 |
+
try:
|
| 255 |
+
service = get_hf_space_crypto_service()
|
| 256 |
+
result = await service.get_categories()
|
| 257 |
+
|
| 258 |
+
if not result["success"]:
|
| 259 |
+
raise HTTPException(
|
| 260 |
+
status_code=503,
|
| 261 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 262 |
+
)
|
| 263 |
+
|
| 264 |
+
return result["data"]
|
| 265 |
+
|
| 266 |
+
except HTTPException:
|
| 267 |
+
raise
|
| 268 |
+
except Exception as e:
|
| 269 |
+
logger.error(f"❌ Categories endpoint failed: {e}")
|
| 270 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
@router.get("/resources/category/{category}")
|
| 274 |
+
async def get_resources_by_category(
|
| 275 |
+
category: str = Path(
|
| 276 |
+
...,
|
| 277 |
+
description="Category name (rpc_nodes, block_explorers, market_data_apis, etc.)"
|
| 278 |
+
)
|
| 279 |
+
):
|
| 280 |
+
"""
|
| 281 |
+
Get resources for a specific category from HF Space API
|
| 282 |
+
|
| 283 |
+
منابع یک دسته خاص
|
| 284 |
+
|
| 285 |
+
Available categories:
|
| 286 |
+
- rpc_nodes (24 resources)
|
| 287 |
+
- block_explorers (33 resources)
|
| 288 |
+
- market_data_apis (33 resources)
|
| 289 |
+
- news_apis (17 resources)
|
| 290 |
+
- sentiment_apis (14 resources)
|
| 291 |
+
- onchain_analytics_apis (14 resources)
|
| 292 |
+
- whale_tracking_apis (10 resources)
|
| 293 |
+
- hf_resources (9 resources)
|
| 294 |
+
- free_http_endpoints (13 resources)
|
| 295 |
+
- local_backend_routes (106 resources)
|
| 296 |
+
- cors_proxies (7 resources)
|
| 297 |
+
- community_sentiment_apis (1 resource)
|
| 298 |
+
|
| 299 |
+
Returns:
|
| 300 |
+
- category: Category name
|
| 301 |
+
- total: Number of resources in category
|
| 302 |
+
- resources: List of resources with name, base_url, auth, endpoints
|
| 303 |
+
"""
|
| 304 |
+
try:
|
| 305 |
+
service = get_hf_space_crypto_service()
|
| 306 |
+
result = await service.get_resources_by_category(category)
|
| 307 |
+
|
| 308 |
+
if not result["success"]:
|
| 309 |
+
raise HTTPException(
|
| 310 |
+
status_code=503,
|
| 311 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 312 |
+
)
|
| 313 |
+
|
| 314 |
+
return result["data"]
|
| 315 |
+
|
| 316 |
+
except HTTPException:
|
| 317 |
+
raise
|
| 318 |
+
except Exception as e:
|
| 319 |
+
logger.error(f"❌ Resources by category endpoint failed: {e}")
|
| 320 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
@router.get("/resources/all")
|
| 324 |
+
async def get_all_resources():
|
| 325 |
+
"""
|
| 326 |
+
Get all resources list from HF Space API
|
| 327 |
+
|
| 328 |
+
لیست همه منابع
|
| 329 |
+
|
| 330 |
+
Returns:
|
| 331 |
+
- total: Total number of resources (281)
|
| 332 |
+
- resources: List of all resources
|
| 333 |
+
"""
|
| 334 |
+
try:
|
| 335 |
+
service = get_hf_space_crypto_service()
|
| 336 |
+
result = await service.get_all_resources()
|
| 337 |
+
|
| 338 |
+
if not result["success"]:
|
| 339 |
+
raise HTTPException(
|
| 340 |
+
status_code=503,
|
| 341 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 342 |
+
)
|
| 343 |
+
|
| 344 |
+
return result["data"]
|
| 345 |
+
|
| 346 |
+
except HTTPException:
|
| 347 |
+
raise
|
| 348 |
+
except Exception as e:
|
| 349 |
+
logger.error(f"❌ All resources endpoint failed: {e}")
|
| 350 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
# ===== SYSTEM STATUS ENDPOINTS =====
|
| 354 |
+
|
| 355 |
+
@router.get("/health")
|
| 356 |
+
async def health_check():
|
| 357 |
+
"""
|
| 358 |
+
Check HF Space API health status
|
| 359 |
+
|
| 360 |
+
بررسی سلامت API
|
| 361 |
+
|
| 362 |
+
Returns:
|
| 363 |
+
- status: Health status
|
| 364 |
+
- resources_loaded: Whether resources are loaded
|
| 365 |
+
- total_categories: Number of categories
|
| 366 |
+
"""
|
| 367 |
+
try:
|
| 368 |
+
service = get_hf_space_crypto_service()
|
| 369 |
+
result = await service.health_check()
|
| 370 |
+
|
| 371 |
+
if not result["success"]:
|
| 372 |
+
return {
|
| 373 |
+
"status": "unavailable",
|
| 374 |
+
"error": result.get("error"),
|
| 375 |
+
"source": "hf_space_crypto_api"
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
return {
|
| 379 |
+
**result["data"],
|
| 380 |
+
"source": "hf_space_crypto_api"
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
except Exception as e:
|
| 384 |
+
return {
|
| 385 |
+
"status": "error",
|
| 386 |
+
"error": str(e),
|
| 387 |
+
"source": "hf_space_crypto_api"
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
|
| 391 |
+
@router.get("/providers")
|
| 392 |
+
async def get_providers_status():
|
| 393 |
+
"""
|
| 394 |
+
Get data providers status from HF Space API
|
| 395 |
+
|
| 396 |
+
وضعیت provider ها
|
| 397 |
+
|
| 398 |
+
Returns:
|
| 399 |
+
- providers: List of providers with status, latency, success rate
|
| 400 |
+
- total: Number of providers
|
| 401 |
+
"""
|
| 402 |
+
try:
|
| 403 |
+
service = get_hf_space_crypto_service()
|
| 404 |
+
result = await service.get_providers_status()
|
| 405 |
+
|
| 406 |
+
if not result["success"]:
|
| 407 |
+
raise HTTPException(
|
| 408 |
+
status_code=503,
|
| 409 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 410 |
+
)
|
| 411 |
+
|
| 412 |
+
return result["data"]
|
| 413 |
+
|
| 414 |
+
except HTTPException:
|
| 415 |
+
raise
|
| 416 |
+
except Exception as e:
|
| 417 |
+
logger.error(f"❌ Providers status endpoint failed: {e}")
|
| 418 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 419 |
+
|
| 420 |
+
|
| 421 |
+
@router.get("/status")
|
| 422 |
+
async def get_system_status():
|
| 423 |
+
"""
|
| 424 |
+
Get system status from HF Space API
|
| 425 |
+
|
| 426 |
+
وضعیت سیستم
|
| 427 |
+
|
| 428 |
+
Returns:
|
| 429 |
+
- status: System status (online, offline)
|
| 430 |
+
- health: System health
|
| 431 |
+
- avg_response_time: Average response time
|
| 432 |
+
- cache_hit_rate: Cache hit rate
|
| 433 |
+
- uptime: System uptime
|
| 434 |
+
"""
|
| 435 |
+
try:
|
| 436 |
+
service = get_hf_space_crypto_service()
|
| 437 |
+
result = await service.get_system_status()
|
| 438 |
+
|
| 439 |
+
if not result["success"]:
|
| 440 |
+
raise HTTPException(
|
| 441 |
+
status_code=503,
|
| 442 |
+
detail=f"HF Space API unavailable: {result.get('error')}"
|
| 443 |
+
)
|
| 444 |
+
|
| 445 |
+
return result["data"]
|
| 446 |
+
|
| 447 |
+
except HTTPException:
|
| 448 |
+
raise
|
| 449 |
+
except Exception as e:
|
| 450 |
+
logger.error(f"❌ System status endpoint failed: {e}")
|
| 451 |
+
raise HTTPException(status_code=500, detail=str(e))
|
backend/services/hf_space_crypto_client.py
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Space Crypto Resources API Client Service
|
| 4 |
+
سرویس کلاینت برای API منابع کریپتو در HuggingFace Space
|
| 5 |
+
|
| 6 |
+
This service provides access to the external HF Space Crypto Resources API:
|
| 7 |
+
https://really-amin-crypto-api-clean.hf.space
|
| 8 |
+
|
| 9 |
+
Features:
|
| 10 |
+
- Market data (top coins, trending)
|
| 11 |
+
- Global market overview
|
| 12 |
+
- Fear & Greed Index
|
| 13 |
+
- Resource database (281 resources in 12 categories)
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
import httpx
|
| 17 |
+
import asyncio
|
| 18 |
+
import logging
|
| 19 |
+
from typing import Dict, Any, List, Optional
|
| 20 |
+
from datetime import datetime, timezone
|
| 21 |
+
from functools import lru_cache
|
| 22 |
+
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
+
# Base URL for the HF Space API
|
| 26 |
+
HF_CRYPTO_API_BASE_URL = "https://really-amin-crypto-api-clean.hf.space"
|
| 27 |
+
|
| 28 |
+
# Cache for resources (they don't change frequently)
|
| 29 |
+
_resources_cache: Dict[str, Any] = {}
|
| 30 |
+
_cache_timestamp: Optional[datetime] = None
|
| 31 |
+
CACHE_TTL_SECONDS = 300 # 5 minutes
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class HFSpaceCryptoService:
|
| 35 |
+
"""
|
| 36 |
+
Service for accessing HuggingFace Space Crypto Resources API
|
| 37 |
+
Follows project patterns with proper error handling and logging
|
| 38 |
+
"""
|
| 39 |
+
|
| 40 |
+
def __init__(self, timeout: int = 15):
|
| 41 |
+
self.base_url = HF_CRYPTO_API_BASE_URL
|
| 42 |
+
self.timeout = timeout
|
| 43 |
+
self._client: Optional[httpx.AsyncClient] = None
|
| 44 |
+
|
| 45 |
+
async def _get_client(self) -> httpx.AsyncClient:
|
| 46 |
+
"""Get or create async HTTP client"""
|
| 47 |
+
if self._client is None or self._client.is_closed:
|
| 48 |
+
self._client = httpx.AsyncClient(timeout=self.timeout)
|
| 49 |
+
return self._client
|
| 50 |
+
|
| 51 |
+
async def close(self):
|
| 52 |
+
"""Close the HTTP client"""
|
| 53 |
+
if self._client and not self._client.is_closed:
|
| 54 |
+
await self._client.aclose()
|
| 55 |
+
|
| 56 |
+
async def _request(self, endpoint: str, params: Dict = None) -> Dict[str, Any]:
|
| 57 |
+
"""
|
| 58 |
+
Make async request to HF Space API with proper error handling
|
| 59 |
+
|
| 60 |
+
Returns standardized response format matching project patterns
|
| 61 |
+
"""
|
| 62 |
+
provider = "HFSpaceCryptoAPI"
|
| 63 |
+
start_time = datetime.now(timezone.utc)
|
| 64 |
+
|
| 65 |
+
try:
|
| 66 |
+
client = await self._get_client()
|
| 67 |
+
url = f"{self.base_url}{endpoint}"
|
| 68 |
+
|
| 69 |
+
response = await client.get(url, params=params)
|
| 70 |
+
response.raise_for_status()
|
| 71 |
+
|
| 72 |
+
data = response.json()
|
| 73 |
+
response_time_ms = (datetime.now(timezone.utc) - start_time).total_seconds() * 1000
|
| 74 |
+
|
| 75 |
+
logger.info(f"✅ {provider} - {endpoint} - {response_time_ms:.0f}ms")
|
| 76 |
+
|
| 77 |
+
return {
|
| 78 |
+
"provider": provider,
|
| 79 |
+
"endpoint": endpoint,
|
| 80 |
+
"data": data,
|
| 81 |
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
| 82 |
+
"response_time_ms": response_time_ms,
|
| 83 |
+
"success": True,
|
| 84 |
+
"error": None
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
except httpx.HTTPStatusError as e:
|
| 88 |
+
logger.error(f"❌ {provider} - {endpoint} - HTTP {e.response.status_code}")
|
| 89 |
+
return {
|
| 90 |
+
"provider": provider,
|
| 91 |
+
"endpoint": endpoint,
|
| 92 |
+
"data": None,
|
| 93 |
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
| 94 |
+
"success": False,
|
| 95 |
+
"error": f"HTTP {e.response.status_code}",
|
| 96 |
+
"error_type": "http_error"
|
| 97 |
+
}
|
| 98 |
+
except httpx.TimeoutException:
|
| 99 |
+
logger.error(f"❌ {provider} - {endpoint} - Timeout")
|
| 100 |
+
return {
|
| 101 |
+
"provider": provider,
|
| 102 |
+
"endpoint": endpoint,
|
| 103 |
+
"data": None,
|
| 104 |
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
| 105 |
+
"success": False,
|
| 106 |
+
"error": "Request timeout",
|
| 107 |
+
"error_type": "timeout"
|
| 108 |
+
}
|
| 109 |
+
except Exception as e:
|
| 110 |
+
logger.error(f"❌ {provider} - {endpoint} - {str(e)}")
|
| 111 |
+
return {
|
| 112 |
+
"provider": provider,
|
| 113 |
+
"endpoint": endpoint,
|
| 114 |
+
"data": None,
|
| 115 |
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
| 116 |
+
"success": False,
|
| 117 |
+
"error": str(e),
|
| 118 |
+
"error_type": "exception"
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
# ===== MARKET DATA =====
|
| 122 |
+
|
| 123 |
+
async def get_top_coins(self, limit: int = 50) -> Dict[str, Any]:
|
| 124 |
+
"""
|
| 125 |
+
Get top coins by market cap
|
| 126 |
+
دریافت برترین ارزها بر اساس مارکت کپ
|
| 127 |
+
"""
|
| 128 |
+
return await self._request("/api/coins/top", params={"limit": limit})
|
| 129 |
+
|
| 130 |
+
async def get_trending(self) -> Dict[str, Any]:
|
| 131 |
+
"""
|
| 132 |
+
Get trending coins
|
| 133 |
+
دریافت ارزهای ترند
|
| 134 |
+
"""
|
| 135 |
+
return await self._request("/api/trending")
|
| 136 |
+
|
| 137 |
+
async def get_market_overview(self) -> Dict[str, Any]:
|
| 138 |
+
"""
|
| 139 |
+
Get global market overview
|
| 140 |
+
خلاصه کلی بازار
|
| 141 |
+
"""
|
| 142 |
+
return await self._request("/api/market")
|
| 143 |
+
|
| 144 |
+
# ===== SENTIMENT =====
|
| 145 |
+
|
| 146 |
+
async def get_global_sentiment(self, timeframe: str = "1D") -> Dict[str, Any]:
|
| 147 |
+
"""
|
| 148 |
+
Get Fear & Greed Index
|
| 149 |
+
شاخص ترس و طمع
|
| 150 |
+
"""
|
| 151 |
+
return await self._request("/api/sentiment/global", params={"timeframe": timeframe})
|
| 152 |
+
|
| 153 |
+
async def get_asset_sentiment(self, symbol: str) -> Dict[str, Any]:
|
| 154 |
+
"""
|
| 155 |
+
Get sentiment for specific asset
|
| 156 |
+
احساسات یک ارز خاص
|
| 157 |
+
"""
|
| 158 |
+
return await self._request(f"/api/sentiment/asset/{symbol}")
|
| 159 |
+
|
| 160 |
+
# ===== RESOURCES DATABASE =====
|
| 161 |
+
|
| 162 |
+
async def get_resources_stats(self) -> Dict[str, Any]:
|
| 163 |
+
"""
|
| 164 |
+
Get resources database statistics
|
| 165 |
+
آمار منابع
|
| 166 |
+
"""
|
| 167 |
+
return await self._request("/api/resources/stats")
|
| 168 |
+
|
| 169 |
+
async def get_categories(self) -> Dict[str, Any]:
|
| 170 |
+
"""
|
| 171 |
+
Get list of resource categories
|
| 172 |
+
لیست دستهبندیها
|
| 173 |
+
"""
|
| 174 |
+
return await self._request("/api/categories")
|
| 175 |
+
|
| 176 |
+
async def get_resources_by_category(self, category: str) -> Dict[str, Any]:
|
| 177 |
+
"""
|
| 178 |
+
Get resources for a specific category
|
| 179 |
+
منابع یک دسته خاص
|
| 180 |
+
|
| 181 |
+
Categories: rpc_nodes, block_explorers, market_data_apis, news_apis,
|
| 182 |
+
sentiment_apis, onchain_analytics_apis, whale_tracking_apis,
|
| 183 |
+
hf_resources, free_http_endpoints, cors_proxies
|
| 184 |
+
"""
|
| 185 |
+
return await self._request(f"/api/resources/category/{category}")
|
| 186 |
+
|
| 187 |
+
async def get_all_resources(self) -> Dict[str, Any]:
|
| 188 |
+
"""
|
| 189 |
+
Get all resources list
|
| 190 |
+
لیست همه منابع
|
| 191 |
+
"""
|
| 192 |
+
return await self._request("/api/resources/list")
|
| 193 |
+
|
| 194 |
+
# ===== SYSTEM STATUS =====
|
| 195 |
+
|
| 196 |
+
async def health_check(self) -> Dict[str, Any]:
|
| 197 |
+
"""Check API health status"""
|
| 198 |
+
return await self._request("/health")
|
| 199 |
+
|
| 200 |
+
async def get_providers_status(self) -> Dict[str, Any]:
|
| 201 |
+
"""Get data providers status"""
|
| 202 |
+
return await self._request("/api/providers")
|
| 203 |
+
|
| 204 |
+
async def get_system_status(self) -> Dict[str, Any]:
|
| 205 |
+
"""Get system status"""
|
| 206 |
+
return await self._request("/api/status")
|
| 207 |
+
|
| 208 |
+
# ===== CONVENIENCE METHODS =====
|
| 209 |
+
|
| 210 |
+
async def get_fear_greed_index(self) -> int:
|
| 211 |
+
"""
|
| 212 |
+
Get current Fear & Greed Index value
|
| 213 |
+
|
| 214 |
+
Returns:
|
| 215 |
+
int: Fear & Greed Index (0-100)
|
| 216 |
+
"""
|
| 217 |
+
result = await self.get_global_sentiment()
|
| 218 |
+
if result["success"] and result["data"]:
|
| 219 |
+
return result["data"].get("fear_greed_index", 50)
|
| 220 |
+
return 50 # Default neutral
|
| 221 |
+
|
| 222 |
+
async def get_btc_price(self) -> float:
|
| 223 |
+
"""
|
| 224 |
+
Get current Bitcoin price
|
| 225 |
+
|
| 226 |
+
Returns:
|
| 227 |
+
float: BTC price in USD
|
| 228 |
+
"""
|
| 229 |
+
result = await self.get_top_coins(limit=1)
|
| 230 |
+
if result["success"] and result["data"]:
|
| 231 |
+
coins = result["data"].get("coins", [])
|
| 232 |
+
if coins:
|
| 233 |
+
return coins[0].get("current_price", 0)
|
| 234 |
+
return 0
|
| 235 |
+
|
| 236 |
+
async def get_total_market_cap(self) -> float:
|
| 237 |
+
"""
|
| 238 |
+
Get total crypto market cap
|
| 239 |
+
|
| 240 |
+
Returns:
|
| 241 |
+
float: Total market cap in USD
|
| 242 |
+
"""
|
| 243 |
+
result = await self.get_market_overview()
|
| 244 |
+
if result["success"] and result["data"]:
|
| 245 |
+
return result["data"].get("total_market_cap", 0)
|
| 246 |
+
return 0
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
# ===== SINGLETON INSTANCE =====
|
| 250 |
+
|
| 251 |
+
_service_instance: Optional[HFSpaceCryptoService] = None
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
def get_hf_space_crypto_service() -> HFSpaceCryptoService:
|
| 255 |
+
"""Get singleton instance of HF Space Crypto Service"""
|
| 256 |
+
global _service_instance
|
| 257 |
+
if _service_instance is None:
|
| 258 |
+
_service_instance = HFSpaceCryptoService()
|
| 259 |
+
return _service_instance
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
# ===== STANDALONE FUNCTIONS (for collectors compatibility) =====
|
| 263 |
+
|
| 264 |
+
async def fetch_hf_space_top_coins(limit: int = 50) -> Dict[str, Any]:
|
| 265 |
+
"""Fetch top coins from HF Space API"""
|
| 266 |
+
service = get_hf_space_crypto_service()
|
| 267 |
+
return await service.get_top_coins(limit)
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
async def fetch_hf_space_trending() -> Dict[str, Any]:
|
| 271 |
+
"""Fetch trending coins from HF Space API"""
|
| 272 |
+
service = get_hf_space_crypto_service()
|
| 273 |
+
return await service.get_trending()
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
async def fetch_hf_space_market_overview() -> Dict[str, Any]:
|
| 277 |
+
"""Fetch market overview from HF Space API"""
|
| 278 |
+
service = get_hf_space_crypto_service()
|
| 279 |
+
return await service.get_market_overview()
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
async def fetch_hf_space_sentiment() -> Dict[str, Any]:
|
| 283 |
+
"""Fetch global sentiment from HF Space API"""
|
| 284 |
+
service = get_hf_space_crypto_service()
|
| 285 |
+
return await service.get_global_sentiment()
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
async def fetch_hf_space_resources(category: Optional[str] = None) -> Dict[str, Any]:
|
| 289 |
+
"""Fetch resources from HF Space API"""
|
| 290 |
+
service = get_hf_space_crypto_service()
|
| 291 |
+
if category:
|
| 292 |
+
return await service.get_resources_by_category(category)
|
| 293 |
+
return await service.get_resources_stats()
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
# ===== TEST =====
|
| 297 |
+
|
| 298 |
+
if __name__ == "__main__":
|
| 299 |
+
async def main():
|
| 300 |
+
service = get_hf_space_crypto_service()
|
| 301 |
+
|
| 302 |
+
print("=" * 60)
|
| 303 |
+
print("Testing HF Space Crypto Service")
|
| 304 |
+
print("=" * 60)
|
| 305 |
+
|
| 306 |
+
# Health check
|
| 307 |
+
print("\n1. Health Check:")
|
| 308 |
+
result = await service.health_check()
|
| 309 |
+
print(f" Success: {result['success']}")
|
| 310 |
+
if result['success']:
|
| 311 |
+
print(f" Status: {result['data'].get('status')}")
|
| 312 |
+
|
| 313 |
+
# Top coins
|
| 314 |
+
print("\n2. Top 3 Coins:")
|
| 315 |
+
result = await service.get_top_coins(limit=3)
|
| 316 |
+
if result['success']:
|
| 317 |
+
for coin in result['data'].get('coins', []):
|
| 318 |
+
print(f" {coin['name']}: ${coin['current_price']:,.2f}")
|
| 319 |
+
|
| 320 |
+
# Sentiment
|
| 321 |
+
print("\n3. Fear & Greed Index:")
|
| 322 |
+
fgi = await service.get_fear_greed_index()
|
| 323 |
+
print(f" Index: {fgi}")
|
| 324 |
+
|
| 325 |
+
# Resources
|
| 326 |
+
print("\n4. Resources Stats:")
|
| 327 |
+
result = await service.get_resources_stats()
|
| 328 |
+
if result['success']:
|
| 329 |
+
print(f" Total: {result['data'].get('total_resources')}")
|
| 330 |
+
print(f" Categories: {result['data'].get('total_categories')}")
|
| 331 |
+
|
| 332 |
+
await service.close()
|
| 333 |
+
print("\n" + "=" * 60)
|
| 334 |
+
print("Tests completed!")
|
| 335 |
+
|
| 336 |
+
asyncio.run(main())
|
backend/services/multi_source_config.json
CHANGED
|
@@ -1,7 +1,39 @@
|
|
| 1 |
{
|
| 2 |
"api_sources": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
"market_prices": {
|
| 4 |
"primary": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
{
|
| 6 |
"name": "coingecko",
|
| 7 |
"url": "https://api.coingecko.com/api/v3",
|
|
@@ -555,6 +587,15 @@
|
|
| 555 |
},
|
| 556 |
"sentiment_data": {
|
| 557 |
"primary": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 558 |
{
|
| 559 |
"name": "alternative_me_fng",
|
| 560 |
"url": "https://api.alternative.me/fng/",
|
|
|
|
| 1 |
{
|
| 2 |
"api_sources": {
|
| 3 |
+
"aggregated_sources": {
|
| 4 |
+
"primary": [
|
| 5 |
+
{
|
| 6 |
+
"name": "hf_crypto_resources_api",
|
| 7 |
+
"url": "https://really-amin-crypto-api-clean.hf.space",
|
| 8 |
+
"auth_required": false,
|
| 9 |
+
"rate_limit": "unlimited",
|
| 10 |
+
"priority": 1,
|
| 11 |
+
"timeout": 15,
|
| 12 |
+
"description": "Comprehensive crypto data API on HuggingFace Spaces",
|
| 13 |
+
"endpoints": {
|
| 14 |
+
"top_coins": "/api/coins/top",
|
| 15 |
+
"trending": "/api/trending",
|
| 16 |
+
"market_overview": "/api/market",
|
| 17 |
+
"sentiment_global": "/api/sentiment/global",
|
| 18 |
+
"resources_stats": "/api/resources/stats",
|
| 19 |
+
"categories": "/api/categories",
|
| 20 |
+
"resources_by_category": "/api/resources/category/{category}"
|
| 21 |
+
},
|
| 22 |
+
"provides": ["market_data", "sentiment", "trending", "resource_database"]
|
| 23 |
+
}
|
| 24 |
+
]
|
| 25 |
+
},
|
| 26 |
"market_prices": {
|
| 27 |
"primary": [
|
| 28 |
+
{
|
| 29 |
+
"name": "hf_crypto_resources_api",
|
| 30 |
+
"url": "https://really-amin-crypto-api-clean.hf.space/api/coins/top",
|
| 31 |
+
"auth_required": false,
|
| 32 |
+
"rate_limit": "unlimited",
|
| 33 |
+
"priority": 0,
|
| 34 |
+
"timeout": 15,
|
| 35 |
+
"note": "Aggregated source - pulls from CoinGecko"
|
| 36 |
+
},
|
| 37 |
{
|
| 38 |
"name": "coingecko",
|
| 39 |
"url": "https://api.coingecko.com/api/v3",
|
|
|
|
| 587 |
},
|
| 588 |
"sentiment_data": {
|
| 589 |
"primary": [
|
| 590 |
+
{
|
| 591 |
+
"name": "hf_crypto_resources_api_sentiment",
|
| 592 |
+
"url": "https://really-amin-crypto-api-clean.hf.space/api/sentiment/global",
|
| 593 |
+
"auth_required": false,
|
| 594 |
+
"rate_limit": "unlimited",
|
| 595 |
+
"priority": 0,
|
| 596 |
+
"timeout": 15,
|
| 597 |
+
"note": "Aggregated source - pulls from Alternative.me"
|
| 598 |
+
},
|
| 599 |
{
|
| 600 |
"name": "alternative_me_fng",
|
| 601 |
"url": "https://api.alternative.me/fng/",
|
collectors/__init__.py
CHANGED
|
@@ -41,6 +41,9 @@ __all__ = [
|
|
| 41 |
"get_blockchair_data",
|
| 42 |
"get_glassnode_metrics",
|
| 43 |
"collect_onchain_data",
|
|
|
|
|
|
|
|
|
|
| 44 |
]
|
| 45 |
|
| 46 |
_EXPORT_MAP: Dict[str, Tuple[str, str]] = {
|
|
@@ -61,6 +64,9 @@ _EXPORT_MAP: Dict[str, Tuple[str, str]] = {
|
|
| 61 |
"get_blockchair_data": ("collectors.onchain", "get_blockchair_data"),
|
| 62 |
"get_glassnode_metrics": ("collectors.onchain", "get_glassnode_metrics"),
|
| 63 |
"collect_onchain_data": ("collectors.onchain", "collect_onchain_data"),
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
|
|
|
|
| 41 |
"get_blockchair_data",
|
| 42 |
"get_glassnode_metrics",
|
| 43 |
"collect_onchain_data",
|
| 44 |
+
# HuggingFace Space Crypto API
|
| 45 |
+
"HFCryptoAPIClient",
|
| 46 |
+
"get_hf_crypto_client",
|
| 47 |
]
|
| 48 |
|
| 49 |
_EXPORT_MAP: Dict[str, Tuple[str, str]] = {
|
|
|
|
| 64 |
"get_blockchair_data": ("collectors.onchain", "get_blockchair_data"),
|
| 65 |
"get_glassnode_metrics": ("collectors.onchain", "get_glassnode_metrics"),
|
| 66 |
"collect_onchain_data": ("collectors.onchain", "collect_onchain_data"),
|
| 67 |
+
# HuggingFace Space Crypto API
|
| 68 |
+
"HFCryptoAPIClient": ("collectors.hf_crypto_api_client", "HFCryptoAPIClient"),
|
| 69 |
+
"get_hf_crypto_client": ("collectors.hf_crypto_api_client", "get_hf_crypto_client"),
|
| 70 |
}
|
| 71 |
|
| 72 |
|
collectors/hf_crypto_api_client.py
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
HuggingFace Crypto Resources API Client
|
| 4 |
+
کلاینت برای API منابع کریپتو در HuggingFace Space
|
| 5 |
+
|
| 6 |
+
این کلاینت برای دسترسی به API منابع کریپتو استفاده میشود:
|
| 7 |
+
https://really-amin-crypto-api-clean.hf.space
|
| 8 |
+
|
| 9 |
+
API Endpoints:
|
| 10 |
+
- /api/coins/top - برترین ارزها
|
| 11 |
+
- /api/trending - ارزهای ترند
|
| 12 |
+
- /api/market - خلاصه بازار
|
| 13 |
+
- /api/sentiment/global - شاخص ترس و طمع
|
| 14 |
+
- /api/resources/stats - آمار منابع
|
| 15 |
+
- /api/categories - لیست دستهبندیها
|
| 16 |
+
- /api/resources/category/{category} - منابع یک دسته
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
import asyncio
|
| 20 |
+
import aiohttp
|
| 21 |
+
import requests
|
| 22 |
+
from typing import Dict, Any, List, Optional
|
| 23 |
+
from datetime import datetime
|
| 24 |
+
import logging
|
| 25 |
+
|
| 26 |
+
logger = logging.getLogger(__name__)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class HFCryptoAPIClient:
|
| 30 |
+
"""
|
| 31 |
+
Client for HuggingFace Crypto Resources API
|
| 32 |
+
کلاینت API منابع کریپتو
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
BASE_URL = "https://really-amin-crypto-api-clean.hf.space"
|
| 36 |
+
|
| 37 |
+
def __init__(self, timeout: int = 15):
|
| 38 |
+
"""
|
| 39 |
+
Initialize client
|
| 40 |
+
|
| 41 |
+
Args:
|
| 42 |
+
timeout: Request timeout in seconds
|
| 43 |
+
"""
|
| 44 |
+
self.timeout = timeout
|
| 45 |
+
self._session = None
|
| 46 |
+
|
| 47 |
+
# ===== SYNC METHODS =====
|
| 48 |
+
|
| 49 |
+
def health_check(self) -> Dict[str, Any]:
|
| 50 |
+
"""Check API health status"""
|
| 51 |
+
return self._get("/health")
|
| 52 |
+
|
| 53 |
+
def get_top_coins(self, limit: int = 50) -> Dict[str, Any]:
|
| 54 |
+
"""
|
| 55 |
+
Get top coins by market cap
|
| 56 |
+
دریافت برترین ارزها
|
| 57 |
+
|
| 58 |
+
Args:
|
| 59 |
+
limit: Number of coins to return (default: 50)
|
| 60 |
+
"""
|
| 61 |
+
return self._get("/api/coins/top", params={"limit": limit})
|
| 62 |
+
|
| 63 |
+
def get_trending(self) -> Dict[str, Any]:
|
| 64 |
+
"""
|
| 65 |
+
Get trending coins
|
| 66 |
+
دریافت ارزهای ترند
|
| 67 |
+
"""
|
| 68 |
+
return self._get("/api/trending")
|
| 69 |
+
|
| 70 |
+
def get_market_overview(self) -> Dict[str, Any]:
|
| 71 |
+
"""
|
| 72 |
+
Get global market overview
|
| 73 |
+
خلاصه کلی بازار
|
| 74 |
+
"""
|
| 75 |
+
return self._get("/api/market")
|
| 76 |
+
|
| 77 |
+
def get_global_sentiment(self, timeframe: str = "1D") -> Dict[str, Any]:
|
| 78 |
+
"""
|
| 79 |
+
Get Fear & Greed Index
|
| 80 |
+
شاخص ترس و طمع
|
| 81 |
+
|
| 82 |
+
Args:
|
| 83 |
+
timeframe: Timeframe (default: "1D")
|
| 84 |
+
"""
|
| 85 |
+
return self._get("/api/sentiment/global", params={"timeframe": timeframe})
|
| 86 |
+
|
| 87 |
+
def get_asset_sentiment(self, symbol: str) -> Dict[str, Any]:
|
| 88 |
+
"""
|
| 89 |
+
Get sentiment for specific asset
|
| 90 |
+
احساسات یک ارز خاص
|
| 91 |
+
|
| 92 |
+
Args:
|
| 93 |
+
symbol: Asset symbol (e.g., "BTC", "ETH")
|
| 94 |
+
"""
|
| 95 |
+
return self._get(f"/api/sentiment/asset/{symbol}")
|
| 96 |
+
|
| 97 |
+
def get_resources_stats(self) -> Dict[str, Any]:
|
| 98 |
+
"""
|
| 99 |
+
Get resources database statistics
|
| 100 |
+
آمار منابع
|
| 101 |
+
"""
|
| 102 |
+
return self._get("/api/resources/stats")
|
| 103 |
+
|
| 104 |
+
def get_categories(self) -> Dict[str, Any]:
|
| 105 |
+
"""
|
| 106 |
+
Get list of resource categories
|
| 107 |
+
لیست دستهبندیها
|
| 108 |
+
"""
|
| 109 |
+
return self._get("/api/categories")
|
| 110 |
+
|
| 111 |
+
def get_resources_by_category(self, category: str) -> Dict[str, Any]:
|
| 112 |
+
"""
|
| 113 |
+
Get resources for a specific category
|
| 114 |
+
منابع یک دسته خاص
|
| 115 |
+
|
| 116 |
+
Args:
|
| 117 |
+
category: Category name (e.g., "rpc_nodes", "market_data_apis")
|
| 118 |
+
"""
|
| 119 |
+
return self._get(f"/api/resources/category/{category}")
|
| 120 |
+
|
| 121 |
+
def get_all_resources(self) -> Dict[str, Any]:
|
| 122 |
+
"""
|
| 123 |
+
Get all resources list
|
| 124 |
+
لیست همه منابع
|
| 125 |
+
"""
|
| 126 |
+
return self._get("/api/resources/list")
|
| 127 |
+
|
| 128 |
+
def get_providers(self) -> Dict[str, Any]:
|
| 129 |
+
"""
|
| 130 |
+
Get data providers status
|
| 131 |
+
وضعیت provider ها
|
| 132 |
+
"""
|
| 133 |
+
return self._get("/api/providers")
|
| 134 |
+
|
| 135 |
+
def get_system_status(self) -> Dict[str, Any]:
|
| 136 |
+
"""
|
| 137 |
+
Get system status
|
| 138 |
+
وضعیت سیستم
|
| 139 |
+
"""
|
| 140 |
+
return self._get("/api/status")
|
| 141 |
+
|
| 142 |
+
def get_news(self, limit: int = 50) -> Dict[str, Any]:
|
| 143 |
+
"""
|
| 144 |
+
Get crypto news
|
| 145 |
+
آخرین اخبار
|
| 146 |
+
|
| 147 |
+
Args:
|
| 148 |
+
limit: Number of articles to return
|
| 149 |
+
"""
|
| 150 |
+
return self._get("/api/news", params={"limit": limit})
|
| 151 |
+
|
| 152 |
+
def get_ohlcv(self, symbol: str = "BTC", interval: str = "1h", limit: int = 100) -> Dict[str, Any]:
|
| 153 |
+
"""
|
| 154 |
+
Get OHLCV data
|
| 155 |
+
دادههای OHLCV
|
| 156 |
+
|
| 157 |
+
Args:
|
| 158 |
+
symbol: Asset symbol
|
| 159 |
+
interval: Time interval
|
| 160 |
+
limit: Number of candles
|
| 161 |
+
"""
|
| 162 |
+
return self._get("/api/ohlcv", params={
|
| 163 |
+
"symbol": symbol,
|
| 164 |
+
"interval": interval,
|
| 165 |
+
"limit": limit
|
| 166 |
+
})
|
| 167 |
+
|
| 168 |
+
def _get(self, endpoint: str, params: Dict = None) -> Dict[str, Any]:
|
| 169 |
+
"""Make GET request"""
|
| 170 |
+
try:
|
| 171 |
+
url = f"{self.BASE_URL}{endpoint}"
|
| 172 |
+
response = requests.get(url, params=params, timeout=self.timeout)
|
| 173 |
+
response.raise_for_status()
|
| 174 |
+
return response.json()
|
| 175 |
+
except requests.RequestException as e:
|
| 176 |
+
logger.error(f"Request failed for {endpoint}: {e}")
|
| 177 |
+
return {"error": str(e), "success": False}
|
| 178 |
+
|
| 179 |
+
# ===== ASYNC METHODS =====
|
| 180 |
+
|
| 181 |
+
async def _get_session(self) -> aiohttp.ClientSession:
|
| 182 |
+
"""Get or create aiohttp session"""
|
| 183 |
+
if self._session is None or self._session.closed:
|
| 184 |
+
self._session = aiohttp.ClientSession(
|
| 185 |
+
timeout=aiohttp.ClientTimeout(total=self.timeout)
|
| 186 |
+
)
|
| 187 |
+
return self._session
|
| 188 |
+
|
| 189 |
+
async def close(self):
|
| 190 |
+
"""Close the session"""
|
| 191 |
+
if self._session and not self._session.closed:
|
| 192 |
+
await self._session.close()
|
| 193 |
+
|
| 194 |
+
async def _async_get(self, endpoint: str, params: Dict = None) -> Dict[str, Any]:
|
| 195 |
+
"""Make async GET request"""
|
| 196 |
+
try:
|
| 197 |
+
session = await self._get_session()
|
| 198 |
+
url = f"{self.BASE_URL}{endpoint}"
|
| 199 |
+
async with session.get(url, params=params) as response:
|
| 200 |
+
response.raise_for_status()
|
| 201 |
+
return await response.json()
|
| 202 |
+
except Exception as e:
|
| 203 |
+
logger.error(f"Async request failed for {endpoint}: {e}")
|
| 204 |
+
return {"error": str(e), "success": False}
|
| 205 |
+
|
| 206 |
+
async def async_get_top_coins(self, limit: int = 50) -> Dict[str, Any]:
|
| 207 |
+
"""Async: Get top coins"""
|
| 208 |
+
return await self._async_get("/api/coins/top", params={"limit": limit})
|
| 209 |
+
|
| 210 |
+
async def async_get_trending(self) -> Dict[str, Any]:
|
| 211 |
+
"""Async: Get trending coins"""
|
| 212 |
+
return await self._async_get("/api/trending")
|
| 213 |
+
|
| 214 |
+
async def async_get_market_overview(self) -> Dict[str, Any]:
|
| 215 |
+
"""Async: Get market overview"""
|
| 216 |
+
return await self._async_get("/api/market")
|
| 217 |
+
|
| 218 |
+
async def async_get_global_sentiment(self) -> Dict[str, Any]:
|
| 219 |
+
"""Async: Get global sentiment"""
|
| 220 |
+
return await self._async_get("/api/sentiment/global")
|
| 221 |
+
|
| 222 |
+
async def async_get_resources_by_category(self, category: str) -> Dict[str, Any]:
|
| 223 |
+
"""Async: Get resources by category"""
|
| 224 |
+
return await self._async_get(f"/api/resources/category/{category}")
|
| 225 |
+
|
| 226 |
+
# ===== UTILITY METHODS =====
|
| 227 |
+
|
| 228 |
+
def get_rpc_nodes(self) -> List[Dict[str, Any]]:
|
| 229 |
+
"""Get all RPC node resources"""
|
| 230 |
+
data = self.get_resources_by_category("rpc_nodes")
|
| 231 |
+
return data.get("resources", [])
|
| 232 |
+
|
| 233 |
+
def get_market_data_apis(self) -> List[Dict[str, Any]]:
|
| 234 |
+
"""Get all market data API resources"""
|
| 235 |
+
data = self.get_resources_by_category("market_data_apis")
|
| 236 |
+
return data.get("resources", [])
|
| 237 |
+
|
| 238 |
+
def get_sentiment_apis(self) -> List[Dict[str, Any]]:
|
| 239 |
+
"""Get all sentiment API resources"""
|
| 240 |
+
data = self.get_resources_by_category("sentiment_apis")
|
| 241 |
+
return data.get("resources", [])
|
| 242 |
+
|
| 243 |
+
def get_block_explorers(self) -> List[Dict[str, Any]]:
|
| 244 |
+
"""Get all block explorer resources"""
|
| 245 |
+
data = self.get_resources_by_category("block_explorers")
|
| 246 |
+
return data.get("resources", [])
|
| 247 |
+
|
| 248 |
+
def get_whale_tracking_apis(self) -> List[Dict[str, Any]]:
|
| 249 |
+
"""Get all whale tracking API resources"""
|
| 250 |
+
data = self.get_resources_by_category("whale_tracking_apis")
|
| 251 |
+
return data.get("resources", [])
|
| 252 |
+
|
| 253 |
+
def get_hf_resources(self) -> List[Dict[str, Any]]:
|
| 254 |
+
"""Get all HuggingFace resources (models/datasets)"""
|
| 255 |
+
data = self.get_resources_by_category("hf_resources")
|
| 256 |
+
return data.get("resources", [])
|
| 257 |
+
|
| 258 |
+
def get_fear_greed_index(self) -> int:
|
| 259 |
+
"""
|
| 260 |
+
Get current Fear & Greed Index value
|
| 261 |
+
|
| 262 |
+
Returns:
|
| 263 |
+
int: Fear & Greed Index (0-100)
|
| 264 |
+
"""
|
| 265 |
+
data = self.get_global_sentiment()
|
| 266 |
+
return data.get("fear_greed_index", 50)
|
| 267 |
+
|
| 268 |
+
def get_btc_price(self) -> float:
|
| 269 |
+
"""
|
| 270 |
+
Get current Bitcoin price
|
| 271 |
+
|
| 272 |
+
Returns:
|
| 273 |
+
float: BTC price in USD
|
| 274 |
+
"""
|
| 275 |
+
data = self.get_top_coins(limit=1)
|
| 276 |
+
coins = data.get("coins", [])
|
| 277 |
+
if coins:
|
| 278 |
+
return coins[0].get("current_price", 0)
|
| 279 |
+
return 0
|
| 280 |
+
|
| 281 |
+
def get_total_market_cap(self) -> float:
|
| 282 |
+
"""
|
| 283 |
+
Get total crypto market cap
|
| 284 |
+
|
| 285 |
+
Returns:
|
| 286 |
+
float: Total market cap in USD
|
| 287 |
+
"""
|
| 288 |
+
data = self.get_market_overview()
|
| 289 |
+
return data.get("total_market_cap", 0)
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
# ===== CONVENIENCE FUNCTIONS =====
|
| 293 |
+
|
| 294 |
+
def get_hf_crypto_client() -> HFCryptoAPIClient:
|
| 295 |
+
"""Get a configured HF Crypto API client instance"""
|
| 296 |
+
return HFCryptoAPIClient(timeout=15)
|
| 297 |
+
|
| 298 |
+
|
| 299 |
+
# ===== TEST =====
|
| 300 |
+
|
| 301 |
+
if __name__ == "__main__":
|
| 302 |
+
# Test the client
|
| 303 |
+
client = HFCryptoAPIClient()
|
| 304 |
+
|
| 305 |
+
print("=" * 60)
|
| 306 |
+
print("Testing HuggingFace Crypto Resources API Client")
|
| 307 |
+
print("=" * 60)
|
| 308 |
+
|
| 309 |
+
# Health check
|
| 310 |
+
print("\n1. Health Check:")
|
| 311 |
+
health = client.health_check()
|
| 312 |
+
print(f" Status: {health.get('status', 'unknown')}")
|
| 313 |
+
print(f" Resources loaded: {health.get('resources_loaded', False)}")
|
| 314 |
+
|
| 315 |
+
# Top coins
|
| 316 |
+
print("\n2. Top 3 Coins:")
|
| 317 |
+
coins = client.get_top_coins(limit=3)
|
| 318 |
+
for coin in coins.get("coins", []):
|
| 319 |
+
print(f" {coin['name']}: ${coin['current_price']:,.2f}")
|
| 320 |
+
|
| 321 |
+
# Market overview
|
| 322 |
+
print("\n3. Market Overview:")
|
| 323 |
+
market = client.get_market_overview()
|
| 324 |
+
print(f" Total Market Cap: ${market.get('total_market_cap', 0):,.0f}")
|
| 325 |
+
print(f" BTC Dominance: {market.get('market_cap_percentage', {}).get('btc', 0):.2f}%")
|
| 326 |
+
|
| 327 |
+
# Sentiment
|
| 328 |
+
print("\n4. Fear & Greed Index:")
|
| 329 |
+
sentiment = client.get_global_sentiment()
|
| 330 |
+
print(f" Index: {sentiment.get('fear_greed_index', 'N/A')}")
|
| 331 |
+
print(f" Sentiment: {sentiment.get('sentiment', 'N/A')}")
|
| 332 |
+
|
| 333 |
+
# Resources stats
|
| 334 |
+
print("\n5. Resources Stats:")
|
| 335 |
+
stats = client.get_resources_stats()
|
| 336 |
+
print(f" Total Resources: {stats.get('total_resources', 0)}")
|
| 337 |
+
print(f" Total Categories: {stats.get('total_categories', 0)}")
|
| 338 |
+
|
| 339 |
+
# Trending
|
| 340 |
+
print("\n6. Trending Coins:")
|
| 341 |
+
trending = client.get_trending()
|
| 342 |
+
for i, coin in enumerate(trending.get("coins", [])[:5], 1):
|
| 343 |
+
print(f" {i}. {coin['name']} ({coin['symbol']})")
|
| 344 |
+
|
| 345 |
+
print("\n" + "=" * 60)
|
| 346 |
+
print("All tests completed!")
|
| 347 |
+
print("=" * 60)
|
config/api_keys.json
CHANGED
|
@@ -64,6 +64,43 @@
|
|
| 64 |
}
|
| 65 |
},
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
"notifications": {
|
| 68 |
"telegram": {
|
| 69 |
"enabled": true,
|
|
|
|
| 64 |
}
|
| 65 |
},
|
| 66 |
|
| 67 |
+
"aggregated_sources": {
|
| 68 |
+
"hf_crypto_resources_api": {
|
| 69 |
+
"name": "Crypto Resources API (HuggingFace Space)",
|
| 70 |
+
"url": "https://really-amin-crypto-api-clean.hf.space",
|
| 71 |
+
"docs_url": "https://really-amin-crypto-api-clean.hf.space/docs",
|
| 72 |
+
"auth_required": false,
|
| 73 |
+
"rate_limit": "unlimited",
|
| 74 |
+
"endpoints": {
|
| 75 |
+
"health": "/health",
|
| 76 |
+
"top_coins": "/api/coins/top",
|
| 77 |
+
"trending": "/api/trending",
|
| 78 |
+
"market_overview": "/api/market",
|
| 79 |
+
"sentiment_global": "/api/sentiment/global",
|
| 80 |
+
"sentiment_asset": "/api/sentiment/asset/{symbol}",
|
| 81 |
+
"resources_stats": "/api/resources/stats",
|
| 82 |
+
"categories": "/api/categories",
|
| 83 |
+
"resources_by_category": "/api/resources/category/{category}",
|
| 84 |
+
"providers": "/api/providers",
|
| 85 |
+
"system_status": "/api/status"
|
| 86 |
+
},
|
| 87 |
+
"categories_available": [
|
| 88 |
+
"rpc_nodes",
|
| 89 |
+
"block_explorers",
|
| 90 |
+
"market_data_apis",
|
| 91 |
+
"news_apis",
|
| 92 |
+
"sentiment_apis",
|
| 93 |
+
"onchain_analytics_apis",
|
| 94 |
+
"whale_tracking_apis",
|
| 95 |
+
"hf_resources",
|
| 96 |
+
"free_http_endpoints",
|
| 97 |
+
"cors_proxies"
|
| 98 |
+
],
|
| 99 |
+
"verified": true,
|
| 100 |
+
"last_verified": "2025-12-12"
|
| 101 |
+
}
|
| 102 |
+
},
|
| 103 |
+
|
| 104 |
"notifications": {
|
| 105 |
"telegram": {
|
| 106 |
"enabled": true,
|
config/service_registry.json
CHANGED
|
@@ -1,6 +1,72 @@
|
|
| 1 |
{
|
| 2 |
"version": "1.0.0",
|
| 3 |
-
"last_updated": "2025-
|
| 4 |
-
"services": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
}
|
| 6 |
-
|
|
|
|
| 1 |
{
|
| 2 |
"version": "1.0.0",
|
| 3 |
+
"last_updated": "2025-12-12T00:00:00Z",
|
| 4 |
+
"services": [
|
| 5 |
+
{
|
| 6 |
+
"id": "hf_crypto_resources_api",
|
| 7 |
+
"name": "Crypto Resources API (HuggingFace Space)",
|
| 8 |
+
"type": "aggregated",
|
| 9 |
+
"description": "Comprehensive cryptocurrency data API hosted on HuggingFace Spaces. Provides market data, sentiment, trending coins, and a database of 281 crypto resources.",
|
| 10 |
+
"base_url": "https://really-amin-crypto-api-clean.hf.space",
|
| 11 |
+
"docs_url": "https://really-amin-crypto-api-clean.hf.space/docs",
|
| 12 |
+
"openapi_url": "https://really-amin-crypto-api-clean.hf.space/openapi.json",
|
| 13 |
+
"auth_required": false,
|
| 14 |
+
"rate_limit": "unlimited",
|
| 15 |
+
"priority": 1,
|
| 16 |
+
"timeout": 15,
|
| 17 |
+
"is_active": true,
|
| 18 |
+
"is_verified": true,
|
| 19 |
+
"endpoints": {
|
| 20 |
+
"health": "/health",
|
| 21 |
+
"resources_stats": "/api/resources/stats",
|
| 22 |
+
"resources_list": "/api/resources/list",
|
| 23 |
+
"categories": "/api/categories",
|
| 24 |
+
"resources_by_category": "/api/resources/category/{category}",
|
| 25 |
+
"top_coins": "/api/coins/top",
|
| 26 |
+
"trending": "/api/trending",
|
| 27 |
+
"market_overview": "/api/market",
|
| 28 |
+
"sentiment_global": "/api/sentiment/global",
|
| 29 |
+
"sentiment_asset": "/api/sentiment/asset/{symbol}",
|
| 30 |
+
"news": "/api/news",
|
| 31 |
+
"system_status": "/api/status",
|
| 32 |
+
"monitoring_status": "/api/monitoring/status",
|
| 33 |
+
"providers": "/api/providers",
|
| 34 |
+
"models_list": "/api/models/list",
|
| 35 |
+
"models_status": "/api/models/status",
|
| 36 |
+
"ohlcv": "/api/ohlcv",
|
| 37 |
+
"agents_status": "/api/agents/status"
|
| 38 |
+
},
|
| 39 |
+
"categories_available": [
|
| 40 |
+
"rpc_nodes",
|
| 41 |
+
"block_explorers",
|
| 42 |
+
"market_data_apis",
|
| 43 |
+
"news_apis",
|
| 44 |
+
"sentiment_apis",
|
| 45 |
+
"onchain_analytics_apis",
|
| 46 |
+
"whale_tracking_apis",
|
| 47 |
+
"community_sentiment_apis",
|
| 48 |
+
"hf_resources",
|
| 49 |
+
"free_http_endpoints",
|
| 50 |
+
"local_backend_routes",
|
| 51 |
+
"cors_proxies"
|
| 52 |
+
],
|
| 53 |
+
"data_sources": {
|
| 54 |
+
"market_data": "CoinGecko (real-time)",
|
| 55 |
+
"sentiment": "Alternative.me Fear & Greed Index (real-time)",
|
| 56 |
+
"trending": "CoinGecko (real-time)"
|
| 57 |
+
},
|
| 58 |
+
"features": [
|
| 59 |
+
"market_prices",
|
| 60 |
+
"market_overview",
|
| 61 |
+
"trending_coins",
|
| 62 |
+
"fear_greed_index",
|
| 63 |
+
"resource_database",
|
| 64 |
+
"websocket_updates"
|
| 65 |
+
],
|
| 66 |
+
"websocket": {
|
| 67 |
+
"url": "wss://really-amin-crypto-api-clean.hf.space/ws",
|
| 68 |
+
"supported": true
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
]
|
| 72 |
}
|
|
|
hf_unified_server.py
CHANGED
|
@@ -40,6 +40,7 @@ from backend.routers.resource_hierarchy_api import router as resource_hierarchy_
|
|
| 40 |
from backend.routers.dynamic_model_api import router as dynamic_model_router
|
| 41 |
from backend.routers.background_worker_api import router as background_worker_router
|
| 42 |
from backend.routers.intelligent_provider_api import router as intelligent_provider_router # NEW: Intelligent load-balanced providers
|
|
|
|
| 43 |
|
| 44 |
# Real AI models registry (shared with admin/extended API)
|
| 45 |
from ai_models import (
|
|
@@ -374,6 +375,13 @@ try:
|
|
| 374 |
except Exception as e:
|
| 375 |
logger.error(f"Failed to include indicators_router: {e}")
|
| 376 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 377 |
# Add routers status endpoint
|
| 378 |
@app.get("/api/routers")
|
| 379 |
async def get_routers_status():
|
|
|
|
| 40 |
from backend.routers.dynamic_model_api import router as dynamic_model_router
|
| 41 |
from backend.routers.background_worker_api import router as background_worker_router
|
| 42 |
from backend.routers.intelligent_provider_api import router as intelligent_provider_router # NEW: Intelligent load-balanced providers
|
| 43 |
+
from backend.routers.hf_space_crypto_api import router as hf_space_crypto_router # HuggingFace Space Crypto Resources API
|
| 44 |
|
| 45 |
# Real AI models registry (shared with admin/extended API)
|
| 46 |
from ai_models import (
|
|
|
|
| 375 |
except Exception as e:
|
| 376 |
logger.error(f"Failed to include indicators_router: {e}")
|
| 377 |
|
| 378 |
+
# HuggingFace Space Crypto Resources API (External aggregated source)
|
| 379 |
+
try:
|
| 380 |
+
app.include_router(hf_space_crypto_router) # HF Space Crypto API (market, sentiment, resources database)
|
| 381 |
+
logger.info("✓ ✅ HF Space Crypto Router loaded (281 resources, 12 categories, market data, sentiment)")
|
| 382 |
+
except Exception as e:
|
| 383 |
+
logger.error(f"Failed to include hf_space_crypto_router: {e}")
|
| 384 |
+
|
| 385 |
# Add routers status endpoint
|
| 386 |
@app.get("/api/routers")
|
| 387 |
async def get_routers_status():
|