|
29 | 29 | # Per-API rate limits (seconds between calls) |
30 | 30 | API_RATE_LIMITS = { |
31 | 31 | "subvortex": 60, # SubVortex API - conservative |
32 | | - "ipinfo": 86.4, # Free tier: 1000 req/day = 86400s/1000 = 86.4s between calls - Highest accuracy (~99%) |
33 | | - "ip_api": 1.5, # Free tier: 45 req/min = 1.33s between calls, use 1.5s for safety (https://ip-api.com/docs/unban) - Very high accuracy (~98%) |
| 32 | + "ipinfo": 90, # Free tier: 1000 req/day = 86400s/1000 = 86.4s between calls - Highest accuracy (~99%) |
| 33 | + "ip_api": 5, # Free tier: 45 req/min = 1.33s between calls, use 1.5s for safety (https://ip-api.com/docs/unban) - Very high accuracy (~98%) |
34 | 34 | "country_is": 10, # Free tier: 1 req/10 seconds per IP (https://country.is/) - Good accuracy (~95%) |
35 | 35 | "my_api": 0, # Custom API - Down! |
36 | 36 | } |
@@ -80,21 +80,28 @@ def get_country(ip: str): |
80 | 80 |
|
81 | 81 | try: |
82 | 82 | _last_call_time[api_name] = now |
| 83 | + |
83 | 84 | country, reason = api_func(ip_ipv4) |
84 | 85 | if country: |
85 | 86 | return country |
| 87 | + |
86 | 88 | if reason: |
87 | 89 | errors.append(f"{api_name}: {reason}") |
88 | 90 |
|
| 91 | + except requests.HTTPError as e: |
| 92 | + status_code = getattr(e.response, 'status_code', 'unknown') |
| 93 | + errors.append(f"{api_name} ({status_code}): {e}") |
| 94 | + |
89 | 95 | except Exception as e: |
90 | 96 | errors.append(f"{api_name}: {e}") |
91 | 97 |
|
92 | 98 | # Build error message with rate limit info |
93 | 99 | all_errors = errors + [ |
94 | 100 | f"{api}: {remaining:.0f}s cooldown" for api, remaining in rate_limited.items() |
95 | 101 | ] |
| 102 | + |
96 | 103 | raise CountryApiException( |
97 | | - f"All APIs failed for {ip_ipv4}: {'; '.join(all_errors)}", rate_limited |
| 104 | + f"All APIs failed for {ip_ipv4} - {'; '.join(all_errors)}", rate_limited |
98 | 105 | ) |
99 | 106 |
|
100 | 107 |
|
|
0 commit comments