|
|
|
|
|
""" |
|
|
Test real providers to verify they actually work |
|
|
بررسی واقعی پرووایدرها برای اطمینان از عملکرد |
|
|
""" |
|
|
|
|
|
import asyncio |
|
|
import httpx |
|
|
import json |
|
|
from datetime import datetime |
|
|
|
|
|
|
|
|
async def test_binance_direct(): |
|
|
"""Test Binance API directly""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing Binance Provider") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
url = "https://api.binance.com/api/v3/klines" |
|
|
params = { |
|
|
"symbol": "BTCUSDT", |
|
|
"interval": "1h", |
|
|
"limit": 5 |
|
|
} |
|
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client: |
|
|
response = await client.get(url, params=params) |
|
|
|
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
print(f"✅ Response Time: {response.elapsed.total_seconds() * 1000:.0f}ms") |
|
|
|
|
|
if response.status_code == 200: |
|
|
data = response.json() |
|
|
print(f"✅ Data Received: {len(data)} candles") |
|
|
print(f"✅ First Candle: {data[0][:6]}") |
|
|
return True, "Binance works perfectly!" |
|
|
else: |
|
|
return False, f"Error: Status {response.status_code}" |
|
|
|
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_coingecko_direct(): |
|
|
"""Test CoinGecko API directly""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing CoinGecko Provider") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
url = "https://api.coingecko.com/api/v3/simple/price" |
|
|
params = { |
|
|
"ids": "bitcoin,ethereum,solana", |
|
|
"vs_currencies": "usd", |
|
|
"include_24hr_change": "true", |
|
|
"include_24hr_vol": "true" |
|
|
} |
|
|
|
|
|
async with httpx.AsyncClient(timeout=15) as client: |
|
|
response = await client.get(url, params=params) |
|
|
|
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
print(f"✅ Response Time: {response.elapsed.total_seconds() * 1000:.0f}ms") |
|
|
|
|
|
if response.status_code == 200: |
|
|
data = response.json() |
|
|
print(f"✅ Coins Received: {list(data.keys())}") |
|
|
print(f"✅ BTC Price: ${data['bitcoin']['usd']:,.2f}") |
|
|
print(f"✅ BTC 24h Change: {data['bitcoin'].get('usd_24h_change', 0):.2f}%") |
|
|
return True, "CoinGecko works perfectly!" |
|
|
else: |
|
|
return False, f"Error: Status {response.status_code}" |
|
|
|
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_kraken_direct(): |
|
|
"""Test Kraken API directly""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing Kraken Provider") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
url = "https://api.kraken.com/0/public/Ticker" |
|
|
params = { |
|
|
"pair": "XXBTZUSD" |
|
|
} |
|
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client: |
|
|
response = await client.get(url, params=params) |
|
|
|
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
print(f"✅ Response Time: {response.elapsed.total_seconds() * 1000:.0f}ms") |
|
|
|
|
|
if response.status_code == 200: |
|
|
data = response.json() |
|
|
if "error" in data and data["error"]: |
|
|
return False, f"Kraken Error: {data['error']}" |
|
|
|
|
|
result = data.get("result", {}) |
|
|
if result: |
|
|
pair_key = list(result.keys())[0] |
|
|
ticker = result[pair_key] |
|
|
print(f"✅ Pair: {pair_key}") |
|
|
print(f"✅ Last Price: ${float(ticker['c'][0]):,.2f}") |
|
|
print(f"✅ 24h Volume: {float(ticker['v'][1]):,.2f}") |
|
|
return True, "Kraken works perfectly!" |
|
|
else: |
|
|
return False, "No data in response" |
|
|
else: |
|
|
return False, f"Error: Status {response.status_code}" |
|
|
|
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_coincap_direct(): |
|
|
"""Test CoinCap API directly""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing CoinCap Provider") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
url = "https://api.coincap.io/v2/assets" |
|
|
params = { |
|
|
"limit": 3 |
|
|
} |
|
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client: |
|
|
response = await client.get(url, params=params) |
|
|
|
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
print(f"✅ Response Time: {response.elapsed.total_seconds() * 1000:.0f}ms") |
|
|
|
|
|
if response.status_code == 200: |
|
|
data = response.json() |
|
|
assets = data.get("data", []) |
|
|
print(f"✅ Assets Received: {len(assets)}") |
|
|
for asset in assets[:3]: |
|
|
print(f" - {asset['symbol']}: ${float(asset['priceUsd']):,.2f}") |
|
|
return True, "CoinCap works perfectly!" |
|
|
else: |
|
|
return False, f"Error: Status {response.status_code}" |
|
|
|
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_fear_greed_index(): |
|
|
"""Test Fear & Greed Index""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing Fear & Greed Index") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
url = "https://api.alternative.me/fng/" |
|
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client: |
|
|
response = await client.get(url) |
|
|
|
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
print(f"✅ Response Time: {response.elapsed.total_seconds() * 1000:.0f}ms") |
|
|
|
|
|
if response.status_code == 200: |
|
|
data = response.json() |
|
|
fng = data.get("data", [{}])[0] |
|
|
print(f"✅ Value: {fng.get('value')}/100") |
|
|
print(f"✅ Classification: {fng.get('value_classification')}") |
|
|
print(f"✅ Timestamp: {fng.get('timestamp')}") |
|
|
return True, "Fear & Greed Index works!" |
|
|
else: |
|
|
return False, f"Error: Status {response.status_code}" |
|
|
|
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_hf_data_engine(): |
|
|
"""Test HF Data Engine if running""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing HF Data Engine") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
base_url = "http://localhost:8000" |
|
|
|
|
|
async with httpx.AsyncClient(timeout=30) as client: |
|
|
|
|
|
response = await client.get(f"{base_url}/api/health") |
|
|
|
|
|
if response.status_code == 200: |
|
|
print(f"✅ HF Engine is RUNNING") |
|
|
data = response.json() |
|
|
print(f"✅ Status: {data.get('status')}") |
|
|
print(f"✅ Uptime: {data.get('uptime')}s") |
|
|
print(f"✅ Providers: {len(data.get('providers', []))}") |
|
|
|
|
|
|
|
|
try: |
|
|
prices_response = await client.get( |
|
|
f"{base_url}/api/prices", |
|
|
params={"symbols": "BTC,ETH"} |
|
|
) |
|
|
if prices_response.status_code == 200: |
|
|
prices_data = prices_response.json() |
|
|
print(f"✅ Prices endpoint works: {len(prices_data.get('data', []))} coins") |
|
|
else: |
|
|
print(f"⚠️ Prices endpoint: Status {prices_response.status_code}") |
|
|
except: |
|
|
print("⚠️ Prices endpoint not accessible") |
|
|
|
|
|
return True, "HF Data Engine works!" |
|
|
else: |
|
|
return False, f"HF Engine returned status {response.status_code}" |
|
|
|
|
|
except httpx.ConnectError: |
|
|
return False, "HF Engine is not running (Connection refused)" |
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def test_fastapi_backend(): |
|
|
"""Test main FastAPI backend""" |
|
|
print("\n" + "="*60) |
|
|
print("🧪 Testing FastAPI Backend") |
|
|
print("="*60) |
|
|
|
|
|
try: |
|
|
base_url = "http://localhost:7860" |
|
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client: |
|
|
response = await client.get(f"{base_url}/health") |
|
|
|
|
|
if response.status_code == 200: |
|
|
print(f"✅ FastAPI Backend is RUNNING") |
|
|
print(f"✅ Status Code: {response.status_code}") |
|
|
|
|
|
|
|
|
endpoints = ["/api/status", "/api/providers"] |
|
|
for endpoint in endpoints: |
|
|
try: |
|
|
resp = await client.get(f"{base_url}{endpoint}") |
|
|
status = "✅" if resp.status_code < 400 else "⚠️" |
|
|
print(f"{status} {endpoint}: Status {resp.status_code}") |
|
|
except: |
|
|
print(f"❌ {endpoint}: Failed") |
|
|
|
|
|
return True, "FastAPI Backend works!" |
|
|
else: |
|
|
return False, f"Backend returned status {response.status_code}" |
|
|
|
|
|
except httpx.ConnectError: |
|
|
return False, "FastAPI Backend is not running" |
|
|
except Exception as e: |
|
|
return False, f"Error: {str(e)}" |
|
|
|
|
|
|
|
|
async def main(): |
|
|
"""Run all tests""" |
|
|
print("\n" + "🚀"*30) |
|
|
print("تست واقعی همه پرووایدرها") |
|
|
print("REAL PROVIDER TESTING") |
|
|
print("🚀"*30) |
|
|
|
|
|
results = {} |
|
|
|
|
|
|
|
|
print("\n📡 Testing External API Providers...") |
|
|
results["Binance"] = await test_binance_direct() |
|
|
await asyncio.sleep(1) |
|
|
|
|
|
results["CoinGecko"] = await test_coingecko_direct() |
|
|
await asyncio.sleep(1) |
|
|
|
|
|
results["Kraken"] = await test_kraken_direct() |
|
|
await asyncio.sleep(1) |
|
|
|
|
|
results["CoinCap"] = await test_coincap_direct() |
|
|
await asyncio.sleep(1) |
|
|
|
|
|
results["Fear & Greed"] = await test_fear_greed_index() |
|
|
await asyncio.sleep(1) |
|
|
|
|
|
|
|
|
print("\n🏠 Testing Internal Services...") |
|
|
results["HF Data Engine"] = await test_hf_data_engine() |
|
|
results["FastAPI Backend"] = await test_fastapi_backend() |
|
|
|
|
|
|
|
|
print("\n" + "="*60) |
|
|
print("📊 TEST SUMMARY / خلاصه تست") |
|
|
print("="*60) |
|
|
|
|
|
working = 0 |
|
|
failed = 0 |
|
|
|
|
|
for name, (success, message) in results.items(): |
|
|
status = "✅ WORKING" if success else "❌ FAILED" |
|
|
print(f"{status} - {name}") |
|
|
print(f" └─ {message}") |
|
|
|
|
|
if success: |
|
|
working += 1 |
|
|
else: |
|
|
failed += 1 |
|
|
|
|
|
print("\n" + "="*60) |
|
|
print(f"✅ Working: {working}/{len(results)}") |
|
|
print(f"❌ Failed: {failed}/{len(results)}") |
|
|
print(f"📊 Success Rate: {(working/len(results)*100):.1f}%") |
|
|
print("="*60) |
|
|
|
|
|
|
|
|
print("\n💡 توصیهها / RECOMMENDATIONS:") |
|
|
|
|
|
if results.get("HF Data Engine", (False, ""))[0]: |
|
|
print("✅ HF Data Engine is running - You can use it!") |
|
|
else: |
|
|
print("⚠️ HF Data Engine is not running. Start it with:") |
|
|
print(" cd hf-data-engine && python main.py") |
|
|
|
|
|
if results.get("FastAPI Backend", (False, ""))[0]: |
|
|
print("✅ FastAPI Backend is running - Dashboard ready!") |
|
|
else: |
|
|
print("⚠️ FastAPI Backend is not running. Start it with:") |
|
|
print(" python app.py") |
|
|
|
|
|
external_working = sum(1 for k, v in results.items() |
|
|
if k not in ["HF Data Engine", "FastAPI Backend"] and v[0]) |
|
|
|
|
|
if external_working >= 3: |
|
|
print(f"✅ {external_working} external APIs working - Good coverage!") |
|
|
else: |
|
|
print(f"⚠️ Only {external_working} external APIs working") |
|
|
print(" This might be due to IP restrictions or rate limits") |
|
|
|
|
|
print("\n✅ Test Complete!") |
|
|
return working, failed |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
working, failed = asyncio.run(main()) |
|
|
exit(0 if failed == 0 else 1) |
|
|
|