|
|
|
|
|
"""
|
|
|
Restricted APIs Configuration
|
|
|
تنظیمات APIهایی که نیاز به Proxy/DNS دارن
|
|
|
|
|
|
فقط APIهایی که واقعاً فیلتر شدن یا محدودیت دارن
|
|
|
"""
|
|
|
|
|
|
from typing import Dict, List
|
|
|
from enum import Enum
|
|
|
|
|
|
|
|
|
class AccessLevel(Enum):
|
|
|
"""سطح دسترسی"""
|
|
|
DIRECT = "direct"
|
|
|
SMART = "smart"
|
|
|
FORCE_PROXY = "force_proxy"
|
|
|
FORCE_DNS = "force_dns"
|
|
|
|
|
|
|
|
|
|
|
|
RESTRICTED_APIS = {
|
|
|
|
|
|
|
|
|
|
|
|
"kucoin": {
|
|
|
"domains": [
|
|
|
"api.kucoin.com",
|
|
|
"api-futures.kucoin.com",
|
|
|
"openapi-v2.kucoin.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.SMART,
|
|
|
"priority": 1,
|
|
|
"reason": "Critical exchange - always use smart access with rotating DNS/Proxy",
|
|
|
"fallback_order": ["direct", "dns_cloudflare", "dns_google", "proxy", "dns_proxy"],
|
|
|
"rotate_dns": True,
|
|
|
"rotate_proxy": True,
|
|
|
"always_secure": True
|
|
|
},
|
|
|
|
|
|
"binance": {
|
|
|
"domains": [
|
|
|
"api.binance.com",
|
|
|
"api1.binance.com",
|
|
|
"api2.binance.com",
|
|
|
"api3.binance.com",
|
|
|
"fapi.binance.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.SMART,
|
|
|
"priority": 1,
|
|
|
"reason": "Critical exchange - always use smart access with rotating DNS/Proxy",
|
|
|
"fallback_order": ["direct", "dns_cloudflare", "dns_google", "proxy", "dns_proxy"],
|
|
|
"rotate_dns": True,
|
|
|
"rotate_proxy": True,
|
|
|
"always_secure": True
|
|
|
},
|
|
|
|
|
|
"bybit": {
|
|
|
"domains": [
|
|
|
"api.bybit.com",
|
|
|
"api-testnet.bybit.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.SMART,
|
|
|
"priority": 2,
|
|
|
"reason": "May have regional restrictions",
|
|
|
"fallback_order": ["direct", "dns_cloudflare", "proxy"]
|
|
|
},
|
|
|
|
|
|
"okx": {
|
|
|
"domains": [
|
|
|
"www.okx.com",
|
|
|
"aws.okx.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.SMART,
|
|
|
"priority": 2,
|
|
|
"reason": "Geo-restrictions in some regions",
|
|
|
"fallback_order": ["direct", "dns_google", "proxy"]
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"coinmarketcap_pro": {
|
|
|
"domains": [
|
|
|
"pro-api.coinmarketcap.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"priority": 3,
|
|
|
"reason": "Usually works directly with API key",
|
|
|
"fallback_order": ["direct", "dns_cloudflare"]
|
|
|
},
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UNRESTRICTED_APIS = {
|
|
|
"coingecko": {
|
|
|
"domains": [
|
|
|
"api.coingecko.com",
|
|
|
"pro-api.coingecko.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Works globally without restrictions"
|
|
|
},
|
|
|
|
|
|
"coinpaprika": {
|
|
|
"domains": [
|
|
|
"api.coinpaprika.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Free API, no restrictions"
|
|
|
},
|
|
|
|
|
|
"coincap": {
|
|
|
"domains": [
|
|
|
"api.coincap.io"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Free API, globally accessible"
|
|
|
},
|
|
|
|
|
|
"coinlore": {
|
|
|
"domains": [
|
|
|
"api.coinlore.net"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Free API, no geo-restrictions"
|
|
|
},
|
|
|
|
|
|
"cryptopanic": {
|
|
|
"domains": [
|
|
|
"cryptopanic.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "News API, works globally"
|
|
|
},
|
|
|
|
|
|
"alternative_me": {
|
|
|
"domains": [
|
|
|
"api.alternative.me"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Fear & Greed index, no restrictions"
|
|
|
},
|
|
|
|
|
|
"blockchain_info": {
|
|
|
"domains": [
|
|
|
"blockchain.info"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Public blockchain explorer"
|
|
|
},
|
|
|
|
|
|
"etherscan": {
|
|
|
"domains": [
|
|
|
"api.etherscan.io"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Public API with key"
|
|
|
},
|
|
|
|
|
|
"bscscan": {
|
|
|
"domains": [
|
|
|
"api.bscscan.com"
|
|
|
],
|
|
|
"access_level": AccessLevel.DIRECT,
|
|
|
"reason": "Public API with key"
|
|
|
},
|
|
|
}
|
|
|
|
|
|
|
|
|
def get_access_config(domain: str) -> Dict:
|
|
|
"""
|
|
|
دریافت تنظیمات دسترسی برای یک domain
|
|
|
|
|
|
Returns:
|
|
|
{
|
|
|
"access_level": AccessLevel,
|
|
|
"use_smart_access": bool,
|
|
|
"fallback_order": List[str]
|
|
|
}
|
|
|
"""
|
|
|
|
|
|
for api_name, config in RESTRICTED_APIS.items():
|
|
|
if domain in config["domains"]:
|
|
|
return {
|
|
|
"api_name": api_name,
|
|
|
"access_level": config["access_level"],
|
|
|
"use_smart_access": config["access_level"] != AccessLevel.DIRECT,
|
|
|
"fallback_order": config.get("fallback_order", ["direct"]),
|
|
|
"priority": config.get("priority", 99),
|
|
|
"reason": config.get("reason", "")
|
|
|
}
|
|
|
|
|
|
|
|
|
for api_name, config in UNRESTRICTED_APIS.items():
|
|
|
if domain in config["domains"]:
|
|
|
return {
|
|
|
"api_name": api_name,
|
|
|
"access_level": config["access_level"],
|
|
|
"use_smart_access": False,
|
|
|
"fallback_order": ["direct"],
|
|
|
"priority": 99,
|
|
|
"reason": config.get("reason", "")
|
|
|
}
|
|
|
|
|
|
|
|
|
return {
|
|
|
"api_name": "unknown",
|
|
|
"access_level": AccessLevel.SMART,
|
|
|
"use_smart_access": True,
|
|
|
"fallback_order": ["direct", "dns_cloudflare", "proxy"],
|
|
|
"priority": 50,
|
|
|
"reason": "Unknown API, using smart access"
|
|
|
}
|
|
|
|
|
|
|
|
|
def should_use_smart_access(url: str) -> bool:
|
|
|
"""
|
|
|
آیا این URL نیاز به Smart Access داره؟
|
|
|
"""
|
|
|
|
|
|
if "://" in url:
|
|
|
domain = url.split("://")[1].split("/")[0]
|
|
|
else:
|
|
|
domain = url.split("/")[0]
|
|
|
|
|
|
config = get_access_config(domain)
|
|
|
return config["use_smart_access"]
|
|
|
|
|
|
|
|
|
def get_restricted_apis_list() -> List[str]:
|
|
|
"""لیست APIهایی که نیاز به Proxy/DNS دارن"""
|
|
|
return list(RESTRICTED_APIS.keys())
|
|
|
|
|
|
|
|
|
def get_unrestricted_apis_list() -> List[str]:
|
|
|
"""لیست APIهایی که مستقیم کار میکنن"""
|
|
|
return list(UNRESTRICTED_APIS.keys())
|
|
|
|
|
|
|
|
|
def get_all_monitored_domains() -> List[str]:
|
|
|
"""همه domainهایی که تحت نظارت هستن"""
|
|
|
domains = []
|
|
|
|
|
|
for config in RESTRICTED_APIS.values():
|
|
|
domains.extend(config["domains"])
|
|
|
|
|
|
for config in UNRESTRICTED_APIS.values():
|
|
|
domains.extend(config["domains"])
|
|
|
|
|
|
return domains
|
|
|
|
|
|
|
|
|
def print_config_summary():
|
|
|
"""چاپ خلاصه تنظیمات"""
|
|
|
print("=" * 60)
|
|
|
print("📋 RESTRICTED APIS CONFIGURATION")
|
|
|
print("=" * 60)
|
|
|
|
|
|
print("\n🔴 APIs that need Proxy/DNS:")
|
|
|
for api_name, config in RESTRICTED_APIS.items():
|
|
|
print(f"\n {api_name.upper()}:")
|
|
|
print(f" Domains: {', '.join(config['domains'])}")
|
|
|
print(f" Access: {config['access_level'].value}")
|
|
|
print(f" Priority: {config['priority']}")
|
|
|
print(f" Reason: {config['reason']}")
|
|
|
|
|
|
print("\n\n✅ APIs that work DIRECT:")
|
|
|
for api_name, config in UNRESTRICTED_APIS.items():
|
|
|
print(f" • {api_name}: {config['domains'][0]}")
|
|
|
|
|
|
print("\n" + "=" * 60)
|
|
|
print(f"Total Restricted: {len(RESTRICTED_APIS)}")
|
|
|
print(f"Total Unrestricted: {len(UNRESTRICTED_APIS)}")
|
|
|
print("=" * 60)
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
print_config_summary()
|
|
|
|
|
|
|