| """
|
| API Configuration Loader
|
| Loads all API sources from all_apis_merged_2025.json
|
| """
|
| import json
|
| import re
|
| from typing import Dict, List, Any
|
|
|
| class APILoader:
|
| def __init__(self, config_file='all_apis_merged_2025.json'):
|
| self.config_file = config_file
|
| self.apis = {}
|
| self.keys = {}
|
| self.cors_proxies = []
|
| self.load_config()
|
|
|
| def load_config(self):
|
| """Load and parse the comprehensive API configuration"""
|
| try:
|
| with open(self.config_file, 'r', encoding='utf-8') as f:
|
| data = json.load(f)
|
|
|
|
|
| self.extract_keys(data)
|
|
|
|
|
| self.extract_cors_proxies(data)
|
|
|
|
|
| self.build_api_registry(data)
|
|
|
| print(f"✓ Loaded {len(self.apis)} API sources")
|
| print(f"✓ Found {len(self.keys)} API keys")
|
| print(f"✓ Configured {len(self.cors_proxies)} CORS proxies")
|
|
|
| except Exception as e:
|
| print(f"✗ Error loading config: {e}")
|
| self.load_defaults()
|
|
|
| def extract_keys(self, data):
|
| """Extract API keys from configuration"""
|
| content = str(data)
|
|
|
|
|
| key_patterns = {
|
| 'TronScan': r'TronScan[:\s]+([a-f0-9-]{36})',
|
| 'BscScan': r'BscScan[:\s]+([A-Z0-9]{34})',
|
| 'Etherscan': r'Etherscan[:\s]+([A-Z0-9]{34})',
|
| 'Etherscan_2': r'Etherscan_2[:\s]+([A-Z0-9]{34})',
|
| 'CoinMarketCap': r'CoinMarketCap[:\s]+([a-f0-9-]{36})',
|
| 'CoinMarketCap_2': r'CoinMarketCap_2[:\s]+([a-f0-9-]{36})',
|
| 'CryptoCompare': r'CryptoCompare[:\s]+([a-f0-9]{40})',
|
| }
|
|
|
| for name, pattern in key_patterns.items():
|
| match = re.search(pattern, content)
|
| if match:
|
| self.keys[name] = match.group(1)
|
|
|
| def extract_cors_proxies(self, data):
|
| """Extract CORS proxy URLs"""
|
| self.cors_proxies = [
|
| 'https://api.allorigins.win/get?url=',
|
| 'https://proxy.cors.sh/',
|
| 'https://proxy.corsfix.com/?url=',
|
| 'https://api.codetabs.com/v1/proxy?quest=',
|
| 'https://thingproxy.freeboard.io/fetch/'
|
| ]
|
|
|
| def build_api_registry(self, data):
|
| """Build comprehensive API registry"""
|
|
|
|
|
| self.apis['CoinGecko'] = {
|
| 'name': 'CoinGecko',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coingecko.com/api/v3/ping',
|
| 'test_field': 'gecko_says',
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
| self.apis['CoinGecko_Price'] = {
|
| 'name': 'CoinGecko Price',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd',
|
| 'test_field': 'bitcoin',
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
| self.apis['Binance'] = {
|
| 'name': 'Binance',
|
| 'category': 'market_data',
|
| 'url': 'https://api.binance.com/api/v3/ping',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
| self.apis['Binance_Price'] = {
|
| 'name': 'Binance BTCUSDT',
|
| 'category': 'market_data',
|
| 'url': 'https://api.binance.com/api/v3/ticker/24hr?symbol=BTCUSDT',
|
| 'test_field': 'symbol',
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
| self.apis['CoinCap'] = {
|
| 'name': 'CoinCap',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coincap.io/v2/assets/bitcoin',
|
| 'test_field': 'data',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
| self.apis['Coinpaprika'] = {
|
| 'name': 'Coinpaprika',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coinpaprika.com/v1/tickers/btc-bitcoin',
|
| 'test_field': 'id',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
| self.apis['CoinLore'] = {
|
| 'name': 'CoinLore',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coinlore.net/api/ticker/?id=90',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
|
|
| self.apis['Alternative.me'] = {
|
| 'name': 'Alternative.me',
|
| 'category': 'sentiment',
|
| 'url': 'https://api.alternative.me/fng/',
|
| 'test_field': 'data',
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
|
|
| self.apis['CryptoPanic'] = {
|
| 'name': 'CryptoPanic',
|
| 'category': 'news',
|
| 'url': 'https://cryptopanic.com/api/v1/posts/?public=true',
|
| 'test_field': 'results',
|
| 'key': None,
|
| 'priority': 1
|
| }
|
|
|
| self.apis['Reddit_Crypto'] = {
|
| 'name': 'Reddit Crypto',
|
| 'category': 'news',
|
| 'url': 'https://www.reddit.com/r/CryptoCurrency/hot.json?limit=5',
|
| 'test_field': 'data',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
|
|
| if 'Etherscan' in self.keys:
|
| self.apis['Etherscan'] = {
|
| 'name': 'Etherscan',
|
| 'category': 'blockchain_explorers',
|
| 'url': f'https://api.etherscan.io/api?module=stats&action=ethsupply&apikey={self.keys["Etherscan"]}',
|
| 'test_field': 'result',
|
| 'key': self.keys['Etherscan'],
|
| 'priority': 1
|
| }
|
|
|
| if 'BscScan' in self.keys:
|
| self.apis['BscScan'] = {
|
| 'name': 'BscScan',
|
| 'category': 'blockchain_explorers',
|
| 'url': f'https://api.bscscan.com/api?module=stats&action=bnbsupply&apikey={self.keys["BscScan"]}',
|
| 'test_field': 'result',
|
| 'key': self.keys['BscScan'],
|
| 'priority': 1
|
| }
|
|
|
| if 'TronScan' in self.keys:
|
| self.apis['TronScan'] = {
|
| 'name': 'TronScan',
|
| 'category': 'blockchain_explorers',
|
| 'url': 'https://apilist.tronscanapi.com/api/system/status',
|
| 'test_field': None,
|
| 'key': self.keys['TronScan'],
|
| 'priority': 1
|
| }
|
|
|
|
|
| self.apis['Blockchair_BTC'] = {
|
| 'name': 'Blockchair Bitcoin',
|
| 'category': 'blockchain_explorers',
|
| 'url': 'https://api.blockchair.com/bitcoin/stats',
|
| 'test_field': 'data',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
| self.apis['Blockchain.info'] = {
|
| 'name': 'Blockchain.info',
|
| 'category': 'blockchain_explorers',
|
| 'url': 'https://blockchain.info/latestblock',
|
| 'test_field': 'height',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
|
|
| self.apis['Ankr_ETH'] = {
|
| 'name': 'Ankr Ethereum',
|
| 'category': 'rpc_nodes',
|
| 'url': 'https://rpc.ankr.com/eth',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 2,
|
| 'method': 'POST'
|
| }
|
|
|
| self.apis['Cloudflare_ETH'] = {
|
| 'name': 'Cloudflare ETH',
|
| 'category': 'rpc_nodes',
|
| 'url': 'https://cloudflare-eth.com',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 2,
|
| 'method': 'POST'
|
| }
|
|
|
|
|
| self.apis['1inch'] = {
|
| 'name': '1inch',
|
| 'category': 'defi',
|
| 'url': 'https://api.1inch.io/v5.0/1/healthcheck',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
|
|
| self.apis['Messari'] = {
|
| 'name': 'Messari',
|
| 'category': 'market_data',
|
| 'url': 'https://data.messari.io/api/v1/assets/bitcoin/metrics',
|
| 'test_field': 'data',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
| self.apis['CoinDesk'] = {
|
| 'name': 'CoinDesk',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coindesk.com/v1/bpi/currentprice.json',
|
| 'test_field': 'bpi',
|
| 'key': None,
|
| 'priority': 2
|
| }
|
|
|
| def load_defaults(self):
|
| """Load minimal default configuration if file loading fails"""
|
| self.apis = {
|
| 'CoinGecko': {
|
| 'name': 'CoinGecko',
|
| 'category': 'market_data',
|
| 'url': 'https://api.coingecko.com/api/v3/ping',
|
| 'test_field': 'gecko_says',
|
| 'key': None,
|
| 'priority': 1
|
| },
|
| 'Binance': {
|
| 'name': 'Binance',
|
| 'category': 'market_data',
|
| 'url': 'https://api.binance.com/api/v3/ping',
|
| 'test_field': None,
|
| 'key': None,
|
| 'priority': 1
|
| }
|
| }
|
|
|
| def get_all_apis(self) -> Dict[str, Dict[str, Any]]:
|
| """Get all configured APIs"""
|
| return self.apis
|
|
|
| def get_apis_by_category(self, category: str) -> Dict[str, Dict[str, Any]]:
|
| """Get APIs filtered by category"""
|
| return {k: v for k, v in self.apis.items() if v['category'] == category}
|
|
|
| def get_categories(self) -> List[str]:
|
| """Get all unique categories"""
|
| return list(set(api['category'] for api in self.apis.values()))
|
|
|
| def add_custom_api(self, name: str, url: str, category: str, test_field: str = None):
|
| """Add a custom API source"""
|
| self.apis[name] = {
|
| 'name': name,
|
| 'category': category,
|
| 'url': url,
|
| 'test_field': test_field,
|
| 'key': None,
|
| 'priority': 3
|
| }
|
| return True
|
|
|
| def remove_api(self, name: str):
|
| """Remove an API source"""
|
| if name in self.apis:
|
| del self.apis[name]
|
| return True
|
| return False
|
|
|
|
|
| api_loader = APILoader()
|
|
|