mirror of
https://github.com/cunnymessiah/keychecker.git
synced 2026-05-10 18:39:04 -07:00
added 11labs support + detect dalle deployments on azure
This commit is contained in:
@@ -43,6 +43,7 @@ class APIKey:
|
||||
self.model = ""
|
||||
self.deployments = []
|
||||
self.unfiltered = False
|
||||
self.dalle_deployments = ""
|
||||
|
||||
elif provider == Provider.VERTEXAI:
|
||||
self.project_id = ""
|
||||
@@ -61,6 +62,13 @@ class APIKey:
|
||||
self.limit_reached = False
|
||||
self.bought_credits = False
|
||||
|
||||
elif provider == Provider.ELEVENLABS:
|
||||
self.characters_left = 0
|
||||
self.usage = ""
|
||||
self.tier = ""
|
||||
self.unlimited = False
|
||||
self.pro_voice_limit = 0
|
||||
|
||||
def clone(self):
|
||||
cloned_key = APIKey(self.provider, self.api_key)
|
||||
cloned_key.__dict__ = self.__dict__.copy()
|
||||
@@ -76,4 +84,5 @@ class Provider(Enum):
|
||||
AZURE = 6
|
||||
VERTEXAI = 7
|
||||
MISTRAL = 8
|
||||
OPENROUTER = 9
|
||||
OPENROUTER = 9
|
||||
ELEVENLABS = 10
|
||||
|
||||
@@ -10,6 +10,8 @@ def check_azure(key: APIKey):
|
||||
if deployments is None:
|
||||
return
|
||||
|
||||
# deal with dall-e separately
|
||||
key.dalle_deployments = [deployment['id'] for deployment in deployments if deployment['model'] == 'dall-e-3']
|
||||
key.deployments = [(deployment['id'], deployment['model'], test_deployment(key, api_key, deployment['id'])) for deployment in deployments if deployment['model'].startswith('gpt')]
|
||||
|
||||
if key.deployments is None or not key.deployments:
|
||||
@@ -72,6 +74,7 @@ def pretty_print_azure_keys(keys):
|
||||
print('-' * 90)
|
||||
print(f'Validated {len(keys)} Azure keys:')
|
||||
unfiltered = 0
|
||||
keys = sorted(keys, key=lambda x: (x.unfiltered, bool(x.dalle_deployments)), reverse=True)
|
||||
for key in keys:
|
||||
if key.unfiltered:
|
||||
unfiltered += 1
|
||||
@@ -79,10 +82,11 @@ def pretty_print_azure_keys(keys):
|
||||
+ f' | best deployment - {key.best_deployment}'
|
||||
+ f' | top model - {key.model}')
|
||||
if key.deployments:
|
||||
key_string += ' | other deployments - ['
|
||||
key_string += ' | other chat deployments - ['
|
||||
for deployment_id, model, filter_status in key.deployments:
|
||||
key_string += (f"'{deployment_id}'" + (' - unfiltered' if filter_status else '') + ', ')
|
||||
key_string = key_string.rstrip(', ') + ']'
|
||||
key_string += (' | !!!UNFILTERED!!!' if key.unfiltered else '')
|
||||
key_string += (f' | dall-e 3 deployments found on - {key.dalle_deployments}' if key.dalle_deployments else '')
|
||||
print(key_string)
|
||||
print(f'\n--- Total Valid Azure Keys: {len(keys)} ({unfiltered} unfiltered) ---\n')
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import APIKey
|
||||
|
||||
|
||||
async def check_elevenlabs(key: APIKey, session):
|
||||
async with session.get('https://api.elevenlabs.io/v1/user/subscription', headers={'xi-api-key': key.api_key}) as response:
|
||||
if response.status != 200:
|
||||
return
|
||||
response = await response.json()
|
||||
try:
|
||||
key.characters_left = int(response['character_limit']) - int(response['character_count'])
|
||||
next_invoice = response['next_invoice']
|
||||
tier_pricing = [33000, 9900, 2200, 500]
|
||||
key.usage = "${:.2f}".format(int(next_invoice['amount_due_cents']) / 100) if next_invoice and int(next_invoice['amount_due_cents']) not in tier_pricing else ''
|
||||
key.tier = response['tier']
|
||||
key.unlimited = response['can_extend_character_limit'] and response['allowed_to_extend_character_limit']
|
||||
if response['can_use_professional_voice_cloning']:
|
||||
key.pro_voice_limit = int(response['professional_voice_limit'])
|
||||
except (KeyError, ValueError):
|
||||
return
|
||||
return True
|
||||
|
||||
|
||||
def pretty_print_elevenlabs_keys(keys):
|
||||
keys_by_tier = {}
|
||||
for key in keys:
|
||||
if key.tier not in keys_by_tier:
|
||||
keys_by_tier[key.tier] = []
|
||||
keys_by_tier[key.tier].append(key)
|
||||
|
||||
tier_order = ['growing_business', 'pro', 'creator', 'starter', 'free']
|
||||
|
||||
print('-' * 90)
|
||||
print(f'Validated {len(keys)} ElevenLabs keys:')
|
||||
for tier in tier_order:
|
||||
if tier in keys_by_tier:
|
||||
keys_in_tier = sorted(keys_by_tier[tier], key=lambda x: x.characters_left, reverse=True)
|
||||
print(f'\n{len(keys_in_tier)} keys found in {tier} tier:')
|
||||
for key in keys_in_tier:
|
||||
print(f'{key.api_key} | {key.characters_left} characters remaining' + (' | !!!unlimited quota!!!' if key.unlimited else '')
|
||||
+ (f' | plan limit exceeded - next invoice {key.usage}' if key.usage else '')
|
||||
+ (f' | pro voice cloning limit of {key.pro_voice_limit}' if key.pro_voice_limit else ''))
|
||||
print(f'\n--- Total Valid ElevenLabs Keys: {len(keys)} ---\n')
|
||||
@@ -4,14 +4,15 @@ a fast, bulk key checker for various AI services
|
||||
Currently supports and validates keys for the services below, and checks for the listed attributes a key might have:
|
||||
|
||||
- OpenAI - (Best model, key in quota, RPM (catches increase requests), tier, list of organizations if applicable, trial key status)
|
||||
- Anthropic - (Pozzed and quotaless check)
|
||||
- Anthropic - (Pozzed status and key tier, along with remaining character quota)
|
||||
- AI21 - (Trial check)
|
||||
- Google MakerSuite (Gemini)
|
||||
- AWS - (Admin status, auto-fetch the region, logging status, username, bedrock status)
|
||||
- Azure - (Auto-fetch all deployments, auto-fetch best deployment/model, filter status)
|
||||
- Azure - (Auto-fetch all deployments, auto-fetch best deployment/model, filter status, dall-e deployment)
|
||||
- Google Cloud Vertex AI - (Requires a key file since oauth tokens expire hourly. Good luck scraping for those.)
|
||||
- MistralAI - (Subscription status)
|
||||
- OpenRouter - (Estimated balance, usage in $, credit limit, RPM, has purchased any credits)
|
||||
- ElevenLabs - (Key tier, remaining characters in plan, detect uncapped char quota, pro voice cloning limit, invoice details on pay as you go plans)
|
||||
|
||||
Always open to adding more services, although I think I've covered all the ones people care about. Nonetheless, feel free to open an issue or PR if you want something else added.
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from Azure import check_azure, pretty_print_azure_keys
|
||||
from VertexAI import check_vertexai, pretty_print_vertexai_keys
|
||||
from Mistral import check_mistral, pretty_print_mistral_keys
|
||||
from OpenRouter import check_openrouter, pretty_print_openrouter_keys
|
||||
from ElevenLabs import check_elevenlabs, pretty_print_elevenlabs_keys
|
||||
|
||||
from APIKey import APIKey, Provider
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
@@ -117,7 +118,7 @@ async def validate_makersuite(key: APIKey, sem):
|
||||
|
||||
async def validate_openrouter(key: APIKey, sem):
|
||||
async with sem, aiohttp.ClientSession() as session:
|
||||
IO.conditional_print(f"Checking OpenRouter: {key.api_key}", args.verbose)
|
||||
IO.conditional_print(f"Checking OpenRouter key: {key.api_key}", args.verbose)
|
||||
if await check_openrouter(key, session) is None:
|
||||
IO.conditional_print(f"Invalid OpenRouter key: {key.api_key}", args.verbose)
|
||||
return
|
||||
@@ -125,6 +126,16 @@ async def validate_openrouter(key: APIKey, sem):
|
||||
api_keys.add(key)
|
||||
|
||||
|
||||
async def validate_elevenlabs(key: APIKey, sem):
|
||||
async with sem, aiohttp.ClientSession() as session:
|
||||
IO.conditional_print(f"Checking ElevenLabs key: {key.api_key}", args.verbose)
|
||||
if await check_elevenlabs(key, session) is None:
|
||||
IO.conditional_print(f"Invalid ElevenLabs key: {key.api_key}", args.verbose)
|
||||
return
|
||||
IO.conditional_print(f"ElevenLabs key '{key.api_key}' is valid", args.verbose)
|
||||
api_keys.add(key)
|
||||
|
||||
|
||||
def validate_aws(key: APIKey):
|
||||
IO.conditional_print(f"Checking AWS key: {key.api_key}", args.verbose)
|
||||
if check_aws(key) is None:
|
||||
@@ -156,6 +167,7 @@ oai_regex = re.compile('(sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20})')
|
||||
anthropic_regex = re.compile(r'sk-ant-api03-[A-Za-z0-9\-_]{93}AA')
|
||||
anthropic_secondary_regex = re.compile(r'sk-ant-[A-Za-z0-9\-_]{86}')
|
||||
ai21_and_mistral_regex = re.compile('[A-Za-z0-9]{32}')
|
||||
elevenlabs_regex = re.compile(r'([a-z0-9]{32})')
|
||||
makersuite_regex = re.compile(r'AIzaSy[A-Za-z0-9\-_]{33}')
|
||||
aws_regex = re.compile(r'^(AKIA[0-9A-Z]{16}):([A-Za-z0-9+/]{40})$')
|
||||
azure_regex = re.compile(r'^(.+):([a-z0-9]{32})$')
|
||||
@@ -212,11 +224,16 @@ async def validate_keys():
|
||||
key_obj = APIKey(Provider.AZURE, key)
|
||||
futures.append(executor.submit(validate_azure, key_obj))
|
||||
else:
|
||||
match = ai21_and_mistral_regex.match(key)
|
||||
match = elevenlabs_regex.match(key)
|
||||
if not match:
|
||||
continue
|
||||
key_obj = APIKey(Provider.AI21, key)
|
||||
tasks.append(validate_ai21_and_mistral(key_obj, concurrent_connections))
|
||||
match = ai21_and_mistral_regex.match(key)
|
||||
if not match:
|
||||
continue
|
||||
key_obj = APIKey(Provider.AI21, key)
|
||||
tasks.append(validate_ai21_and_mistral(key_obj, concurrent_connections))
|
||||
else:
|
||||
key_obj = APIKey(Provider.ELEVENLABS, key)
|
||||
tasks.append(validate_elevenlabs(key_obj, concurrent_connections))
|
||||
results = await asyncio.gather(*tasks)
|
||||
for result in results:
|
||||
if result is not None:
|
||||
@@ -227,7 +244,7 @@ async def validate_keys():
|
||||
futures.clear()
|
||||
|
||||
|
||||
def get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, valid_makersuite_keys, valid_aws_keys, valid_azure_keys, valid_vertexai_keys, valid_mistral_keys, valid_openrouter_keys):
|
||||
def get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, valid_makersuite_keys, valid_aws_keys, valid_azure_keys, valid_vertexai_keys, valid_mistral_keys, valid_openrouter_keys, valid_elevenlabs_keys):
|
||||
valid_oai_keys_set = set([key.api_key for key in valid_oai_keys])
|
||||
valid_anthropic_keys_set = set([key.api_key for key in valid_anthropic_keys])
|
||||
valid_ai21_keys_set = set([key.api_key for key in valid_ai21_keys])
|
||||
@@ -237,8 +254,9 @@ def get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, vali
|
||||
valid_vertexai_keys_set = set([key.api_key for key in valid_vertexai_keys])
|
||||
valid_mistral_keys_set = set([key.api_key for key in valid_mistral_keys])
|
||||
valid_openrouter_keys_set = set([key.api_key for key in valid_openrouter_keys])
|
||||
valid_elevenlabs_set = set([key.api_key for key in valid_elevenlabs_keys])
|
||||
|
||||
invalid_keys = inputted_keys - valid_oai_keys_set - valid_anthropic_keys_set - valid_ai21_keys_set - valid_makersuite_keys_set - valid_aws_keys_set - valid_azure_keys_set - valid_vertexai_keys_set - valid_mistral_keys_set - valid_openrouter_keys_set
|
||||
invalid_keys = inputted_keys - valid_oai_keys_set - valid_anthropic_keys_set - valid_ai21_keys_set - valid_makersuite_keys_set - valid_aws_keys_set - valid_azure_keys_set - valid_vertexai_keys_set - valid_mistral_keys_set - valid_openrouter_keys_set - valid_elevenlabs_set
|
||||
invalid_keys_len = len(invalid_keys) + len(cloned_keys) if cloned_keys else len(invalid_keys)
|
||||
if invalid_keys_len < 1:
|
||||
return
|
||||
@@ -259,6 +277,7 @@ def output_keys():
|
||||
valid_vertexai_keys = []
|
||||
valid_mistral_keys = []
|
||||
valid_openrouter_keys = []
|
||||
valid_elevenlabs_keys = []
|
||||
|
||||
for key in api_keys:
|
||||
if key.provider == Provider.OPENAI:
|
||||
@@ -279,6 +298,9 @@ def output_keys():
|
||||
valid_mistral_keys.append(key)
|
||||
elif key.provider == Provider.OPENROUTER:
|
||||
valid_openrouter_keys.append(key)
|
||||
elif key.provider == Provider.ELEVENLABS:
|
||||
valid_elevenlabs_keys.append(key)
|
||||
|
||||
if should_write:
|
||||
output_filename = "key_snapshots.txt"
|
||||
sys.stdout = IO(output_filename)
|
||||
@@ -289,7 +311,7 @@ def output_keys():
|
||||
print(f"Key snapshot from {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print("#" * 90)
|
||||
print(f'\n--- Checked {len(inputted_keys)} keys | {invalid_keys} were invalid ---')
|
||||
get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, valid_makersuite_keys, valid_aws_keys, valid_azure_keys, valid_vertexai_keys, valid_mistral_keys, valid_openrouter_keys)
|
||||
get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, valid_makersuite_keys, valid_aws_keys, valid_azure_keys, valid_vertexai_keys, valid_mistral_keys, valid_openrouter_keys, valid_elevenlabs_keys)
|
||||
print()
|
||||
if valid_oai_keys:
|
||||
pretty_print_oai_keys(valid_oai_keys, cloned_keys)
|
||||
@@ -309,6 +331,8 @@ def output_keys():
|
||||
pretty_print_mistral_keys(valid_mistral_keys)
|
||||
if valid_openrouter_keys:
|
||||
pretty_print_openrouter_keys(valid_openrouter_keys)
|
||||
if valid_elevenlabs_keys:
|
||||
pretty_print_elevenlabs_keys(valid_elevenlabs_keys)
|
||||
else:
|
||||
# ai21, openrouter and vertex keys aren't supported in proxies so no point outputting them, filtered azure keys should be excluded.
|
||||
print("OPENAI_KEY=" + ','.join(key.api_key for key in valid_oai_keys))
|
||||
|
||||
Reference in New Issue
Block a user