Update app.py
Browse files
app.py
CHANGED
|
@@ -8,13 +8,72 @@ from api_usage import (
|
|
| 8 |
check_key_aws_availability, check_key_or_availability, check_key_or_limits,
|
| 9 |
check_gcp_anthropic, check_groq_status, check_nai_status,
|
| 10 |
check_elevenlabs_status, check_xai_status, check_stability_status,
|
| 11 |
-
check_deepseek_status
|
| 12 |
)
|
| 13 |
|
| 14 |
async def sort_key(key, rate_limit, claude_model):
|
|
|
|
|
|
|
|
|
|
| 15 |
_key = key.strip()
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
async def sort_keys(keys_text, rate_limit, claude_model):
|
| 20 |
"""
|
|
@@ -27,6 +86,7 @@ async def sort_keys(keys_text, rate_limit, claude_model):
|
|
| 27 |
results[k] = await sort_key(k, rate_limit, claude_model)
|
| 28 |
return results
|
| 29 |
|
|
|
|
| 30 |
def clear_inputs(text):
|
| 31 |
return ""
|
| 32 |
|
|
@@ -50,7 +110,7 @@ with gr.Blocks() as demo:
|
|
| 50 |
with gr.Column():
|
| 51 |
key_input = gr.Textbox(
|
| 52 |
lines=5,
|
| 53 |
-
placeholder="sk-...
|
| 54 |
label="API Keys (one per line)"
|
| 55 |
)
|
| 56 |
claude_model = gr.Dropdown(
|
|
|
|
| 8 |
check_key_aws_availability, check_key_or_availability, check_key_or_limits,
|
| 9 |
check_gcp_anthropic, check_groq_status, check_nai_status,
|
| 10 |
check_elevenlabs_status, check_xai_status, check_stability_status,
|
| 11 |
+
check_deepseek_status, not_supported
|
| 12 |
)
|
| 13 |
|
| 14 |
async def sort_key(key, rate_limit, claude_model):
|
| 15 |
+
"""
|
| 16 |
+
Check a single API key and return its info dict.
|
| 17 |
+
"""
|
| 18 |
_key = key.strip()
|
| 19 |
+
|
| 20 |
+
# OpenRouter
|
| 21 |
+
if re.match(r"^sk-or-v1-[a-z0-9]{64}$", _key):
|
| 22 |
+
return get_key_openrouter_info(_key)
|
| 23 |
+
# Anthropic Claude
|
| 24 |
+
if (re.match(r"^sk-ant-api03-[A-Za-z0-9\-_]{93}AA$", _key)
|
| 25 |
+
or (_key.startswith("sk-ant-") and len(_key) == 93)
|
| 26 |
+
or (len(_key) == 89 and re.match(r"^sk-[A-Za-z0-9]{86}$", _key))):
|
| 27 |
+
return await get_key_ant_info(_key, rate_limit, claude_model)
|
| 28 |
+
# Stability AI
|
| 29 |
+
if re.match(r"^sk-[A-Za-z0-9]{48}$", _key) and len(_key) == 51 and 'T3BlbkFJ' not in _key:
|
| 30 |
+
return get_key_stability_info(_key)
|
| 31 |
+
# Deepseek
|
| 32 |
+
if re.match(r"^sk-[a-f0-9]{32}$", _key):
|
| 33 |
+
return get_key_deepseek_info(_key)
|
| 34 |
+
# OpenAI
|
| 35 |
+
if _key.startswith("sk-"):
|
| 36 |
+
return get_key_oai_info(_key)
|
| 37 |
+
# Google Gemini
|
| 38 |
+
if _key.startswith("AIzaSy"):
|
| 39 |
+
return get_key_gemini_info(_key)
|
| 40 |
+
# NovelAI
|
| 41 |
+
if _key.startswith("pst-"):
|
| 42 |
+
return get_key_nai_info(_key)
|
| 43 |
+
# Replicate
|
| 44 |
+
if ((_key.startswith("r8_") and len(_key) == 40)
|
| 45 |
+
or (_key.islower() and len(_key) == 40)):
|
| 46 |
+
return get_key_replicate_info(_key)
|
| 47 |
+
# xAI Grok
|
| 48 |
+
if _key.startswith("xai-"):
|
| 49 |
+
return get_key_xai_info(_key)
|
| 50 |
+
# Azure OpenAI
|
| 51 |
+
if len(_key.split(':')) == 2 and _key.split(':')[1].islower() and len(_key.split(':')[1]) == 32:
|
| 52 |
+
endpoint, api_key = _key.split(':')
|
| 53 |
+
return get_key_azure_info(f"{endpoint}.openai.azure.com", api_key)
|
| 54 |
+
if "openai.azure.com" in _key:
|
| 55 |
+
endpoint, api_key = _key.split(';')
|
| 56 |
+
return get_key_azure_info(endpoint, api_key)
|
| 57 |
+
# AWS
|
| 58 |
+
if _key.startswith("AKIA") and len(_key.split(':')[0]) == 20 and _key.split(':')[0].isupper():
|
| 59 |
+
return await get_key_aws_info(_key)
|
| 60 |
+
# ElevenLabs
|
| 61 |
+
if re.match(r"^[a-f0-9]{32}$", _key) or re.match(r"^sk_[a-f0-9]{48}$", _key):
|
| 62 |
+
return get_key_elevenlabs_info(_key)
|
| 63 |
+
# Mistral AI
|
| 64 |
+
if re.match(r"^[A-Za-z0-9]{32}$", _key):
|
| 65 |
+
return get_key_mistral_info(_key)
|
| 66 |
+
# Groq
|
| 67 |
+
if re.match(r"^gsk_[A-Za-z0-9]{20}WGdyb3FY[A-Za-z0-9]{24}$", _key):
|
| 68 |
+
return get_key_groq_info(_key)
|
| 69 |
+
# GCP Anthropic
|
| 70 |
+
if re.match(r"[\w\-]+:[\w\-@\.]+:[\w\-]+:.+", _key):
|
| 71 |
+
return await get_key_gcp_info(_key, 0)
|
| 72 |
+
if re.match(r"[\w\-]+:[\w\-@\.]+:.+\\n", _key):
|
| 73 |
+
return await get_key_gcp_info(_key, 1)
|
| 74 |
+
|
| 75 |
+
# Fallback for unsupported formats
|
| 76 |
+
return not_supported(_key)
|
| 77 |
|
| 78 |
async def sort_keys(keys_text, rate_limit, claude_model):
|
| 79 |
"""
|
|
|
|
| 86 |
results[k] = await sort_key(k, rate_limit, claude_model)
|
| 87 |
return results
|
| 88 |
|
| 89 |
+
|
| 90 |
def clear_inputs(text):
|
| 91 |
return ""
|
| 92 |
|
|
|
|
| 110 |
with gr.Column():
|
| 111 |
key_input = gr.Textbox(
|
| 112 |
lines=5,
|
| 113 |
+
placeholder="sk-... or AKIA...",
|
| 114 |
label="API Keys (one per line)"
|
| 115 |
)
|
| 116 |
claude_model = gr.Dropdown(
|