#!/usr/bin/env python3 """Fast parallel LLM API key verifier — Python version. Uses urllib instead of spawning curl subprocesses per key. """ import time from pathlib import Path from concurrent.futures import ThreadPoolExecutor, as_completed from collections import defaultdict import urllib.request import urllib.error RESULTS_DIR = Path(__file__).parent / "results" KEYS_FILE = RESULTS_DIR / "extracted_keys.txt" LIVE_FILE = RESULTS_DIR / "live_keys_raw.txt" # Provider verify configs VERIFY_CONFIGS = { "OpenAI": {"url": "https://api.openai.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "Anthropic": {"url": "https://api.anthropic.com/v1/models", "headers": {"x-api-key": "{key}", "anthropic-version": "2023-06-01"}}, "Google": {"url": "https://generativelanguage.googleapis.com/v1/models?key={key}", "headers": {}}, "HuggingFace": {"url": "https://huggingface.co/api/whoami-v2", "headers": {"Authorization": "Bearer {key}"}}, "Groq": {"url": "https://api.groq.com/openai/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "Replicate": {"url": "https://api.replicate.com/v1/account", "headers": {"Authorization": "Token {key}"}}, "TogetherAI": {"url": "https://api.together.xyz/models", "headers": {"Authorization": "Bearer {key}"}}, "DeepSeek": {"url": "https://api.deepseek.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "OpenRouter": {"url": "https://openrouter.ai/api/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "Perplexity": {"url": "https://api.perplexity.ai/chat/completions", "headers": {"Authorization": "Bearer {key}"}}, "VolcanoArk": {"url": "https://ark.cn-beijing.volces.com/api/v3/models", "headers": {"Authorization": "Bearer {key}"}}, "ZhipuAI": {"url": "https://open.bigmodel.cn/api/paas/v4/models", "headers": {"Authorization": "Bearer {key}"}}, "DashScope": {"url": "https://dashscope.aliyuncs.com/compatible-mode/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "Moonshot": {"url": "https://api.moonshot.cn/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "MiniMax": {"url": "https://api.minimaxi.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "LingyiWanwu": {"url": "https://api.lingyiwanwu.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "StepFun": {"url": "https://api.stepfun.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "SiliconFlow": {"url": "https://api.siliconflow.cn/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "LongCat": {"url": "https://api.longcat.chat/openai/models", "headers": {"Authorization": "Bearer {key}"}}, "OllamaCloud": {"url": "https://api.ollama.com/api/tags", "headers": {"Authorization": "Bearer {key}"}}, "FreeModel": {"url": "https://api.freemodel.dev/v1/models", "headers": {"Authorization": "Bearer {key}"}}, "XKiro": {"url": "https://api.xkiro.com/v1/models", "headers": {"Authorization": "Bearer {key}"}}, } # Providers to skip (too many false positives, or no simple verify endpoint) SKIP_PROVIDERS = { "Mistral", "Cohere", "AzureOpenAI", "iFlytekSpark", "iFlytekCodingPlan", "TencentHunyuan", "BaiduQianfan", "CSDNCodingPlan", "HuaweiCodeArts", "MiMo", "InfiniAI", "JDCloud", "MooreThreads", "Kuaishou", "UCloud", "Anomaly", "ChinaUnicom", "SCNet", "AlibabaCodingPlan", "Zyloo", } def verify_key(provider, key): """Verify a key against its provider API. Returns True if live, False if dead, None if skipped.""" if provider in SKIP_PROVIDERS: return None if provider not in VERIFY_CONFIGS: return None cfg = VERIFY_CONFIGS[provider] url = cfg["url"].replace("{key}", key) headers = {hname: hval.replace("{key}", key) for hname, hval in cfg["headers"].items()} req = urllib.request.Request(url, headers=headers, method="GET") try: with urllib.request.urlopen(req, timeout=10) as resp: code = resp.getcode() return code == 200 or (provider == "Perplexity" and code not in (401, 0)) except urllib.error.HTTPError as e: code = e.code if provider == "Perplexity": return code not in (401, 0) return code == 200 except Exception: return False def main(): # Read keys keys = [] with open(KEYS_FILE) as f: for line in f: line = line.strip() if not line: continue parts = line.split("|", 3) if len(parts) >= 2: provider = parts[0] key = parts[1] url = parts[2] if len(parts) > 2 else "" desc = parts[3] if len(parts) > 3 else "" keys.append((provider, key, url, desc)) print(f"Total keys: {len(keys)}") # Group by provider and deduplicate by_provider = defaultdict(dict) # provider -> {key: (url, desc)} for provider, key, url, desc in keys: if provider in SKIP_PROVIDERS: continue if provider not in VERIFY_CONFIGS: continue if key not in by_provider[provider]: by_provider[provider][key] = (url, desc) # Print summary print("\nKeys by provider (deduplicated):") total_to_verify = 0 for provider in sorted(by_provider.keys()): n = len(by_provider[provider]) total_to_verify += n print(f" {provider:20s}: {n:6d}") print(f" {'TOTAL':20s}: {total_to_verify:6d}") # Build verify list to_verify = [] for provider, keydict in by_provider.items(): for key, (url, desc) in keydict.items(): to_verify.append((provider, key, url, desc)) # Verify in parallel live_keys = [] dead_count = 0 processed = 0 start_time = time.time() print(f"\nVerifying {len(to_verify)} keys with 30 threads...") with ThreadPoolExecutor(max_workers=30) as pool: futures = {pool.submit(verify_key, p, k): (p, k, u, d) for p, k, u, d in to_verify} for future in as_completed(futures): provider, key, url, desc = futures[future] processed += 1 try: result = future.result() except Exception: result = False if result is True: live_keys.append((provider, key, url, desc)) elif result is False: dead_count += 1 if processed % 1000 == 0: elapsed = time.time() - start_time rate = processed / elapsed print(f" [{processed}/{len(to_verify)}] live={len(live_keys)} dead={dead_count} ({rate:.0f}/s)") elapsed = time.time() - start_time print(f"\nDone in {elapsed:.1f}s: {len(live_keys)} live, {dead_count} dead") # Write results with open(LIVE_FILE, "w") as f: for provider, key, url, desc in sorted(live_keys): f.write(f"LIVE|{provider}|{key}|{url}|{desc}\n") print(f"Live keys written to: {LIVE_FILE}") # Print live keys by provider live_by_provider = defaultdict(int) for provider, key, url, desc in live_keys: live_by_provider[provider] += 1 print("\nLive keys by provider:") for provider in sorted(live_by_provider.keys()): print(f" {provider:20s}: {live_by_provider[provider]}") if __name__ == "__main__": main()