mirror of
https://github.com/cunnymessiah/keychecker.git
synced 2026-05-10 18:39:04 -07:00
long overdue
This commit is contained in:
@@ -50,6 +50,7 @@ class APIKey:
|
|||||||
|
|
||||||
elif provider == Provider.VERTEXAI:
|
elif provider == Provider.VERTEXAI:
|
||||||
self.project_id = ""
|
self.project_id = ""
|
||||||
|
self.has_opus = False
|
||||||
|
|
||||||
elif provider == Provider.MISTRAL:
|
elif provider == Provider.MISTRAL:
|
||||||
self.subbed = False
|
self.subbed = False
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Currently supports and validates keys for the services below, and checks for the
|
|||||||
- Google MakerSuite (List of available models + billing status)
|
- Google MakerSuite (List of available models + billing status)
|
||||||
- AWS - (Admin status, auto-fetch the region, logging status, username, bedrock status + enabled models)
|
- AWS - (Admin status, auto-fetch the region, logging status, username, bedrock status + enabled models)
|
||||||
- Azure - (Auto-fetch all deployments, auto-fetch best deployment/model, filter status, dall-e deployment)
|
- 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.)
|
- Google Cloud Vertex AI - (Requires a key file since oauth tokens expire hourly.)
|
||||||
- MistralAI - (Subscription status)
|
- MistralAI - (Subscription status)
|
||||||
- OpenRouter - (Estimated balance, usage in $, credit limit, RPM, has purchased any credits)
|
- 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)
|
- ElevenLabs - (Key tier, remaining characters in plan, detect uncapped char quota, pro voice cloning limit, invoice details on pay as you go plans)
|
||||||
|
|||||||
+61
-21
@@ -1,18 +1,15 @@
|
|||||||
|
import asyncio
|
||||||
import APIKey
|
import APIKey
|
||||||
import json
|
import json
|
||||||
import vertexai
|
|
||||||
from google.cloud import aiplatform
|
|
||||||
from google.oauth2 import service_account
|
from google.oauth2 import service_account
|
||||||
import google.api_core.exceptions
|
from google.auth.transport.requests import Request
|
||||||
from vertexai.language_models import TextGenerationModel
|
|
||||||
|
location = 'us-east5'
|
||||||
|
model = 'claude-3-opus@20240229'
|
||||||
|
|
||||||
|
|
||||||
location = 'us-central1' # location doesn't matter unlike azure/aws
|
async def check_vertexai(key: APIKey, session):
|
||||||
|
|
||||||
|
|
||||||
def check_vertexai(key: APIKey):
|
|
||||||
try:
|
try:
|
||||||
credentials = service_account.Credentials.from_service_account_file(key.api_key)
|
|
||||||
with open(key.api_key, 'r') as file:
|
with open(key.api_key, 'r') as file:
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
if data.get('type') != 'service_account':
|
if data.get('type') != 'service_account':
|
||||||
@@ -23,25 +20,68 @@ def check_vertexai(key: APIKey):
|
|||||||
return
|
return
|
||||||
key.project_id = project_id
|
key.project_id = project_id
|
||||||
|
|
||||||
aiplatform.init(credentials=credentials, location=location, project=key.project_id)
|
credentials = service_account.Credentials.from_service_account_file(
|
||||||
test_model_response(key, credentials)
|
key.api_key,
|
||||||
|
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
||||||
|
)
|
||||||
|
credentials.refresh(Request())
|
||||||
|
|
||||||
except google.api_core.exceptions.InvalidArgument:
|
key.has_opus = await test_model_response(key, credentials.token, session)
|
||||||
key.api_key = f'"{key.api_key}"'
|
return True
|
||||||
return True # if we get to the stage where google yells at us for a bad parameter, 99% sure the key works.
|
|
||||||
except Exception as e:
|
except Exception:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def test_model_response(key: APIKey, credentials):
|
async def test_model_response(key: APIKey, access_token, session):
|
||||||
vertexai.init(project=key.project_id, location=location, credentials=credentials)
|
url = f"https://{location}-aiplatform.googleapis.com/v1/projects/{key.project_id}/locations/{location}/publishers/anthropic/models/{model}:rawPredict"
|
||||||
model = TextGenerationModel.from_pretrained("text-bison@002")
|
|
||||||
model.predict("bweh", **{"temperature": 0.1, "max_output_tokens": 0})
|
headers = {
|
||||||
|
"Authorization": f"Bearer {access_token}",
|
||||||
|
"Content-Type": "application/json; charset=utf-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"anthropic_version": "vertex-2023-10-16",
|
||||||
|
"messages": [
|
||||||
|
{'role': 'user', 'content': ''}
|
||||||
|
],
|
||||||
|
"max_tokens": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in range(5):
|
||||||
|
try:
|
||||||
|
async with session.post(url, headers=headers, json=data) as response:
|
||||||
|
resp = await response.json()
|
||||||
|
if response.status == 429:
|
||||||
|
print(f"Rate limited on vertexai model response, retrying in 5 seconds (attempt {i} of 5)")
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
continue
|
||||||
|
# returned on non enabled models afaik, couldn't test on the anthropic models though since they're all enabled on my service account
|
||||||
|
elif response.status == 400 and resp.get('error', {}).get('status') == 'FAILED_PRECONDITION':
|
||||||
|
return False
|
||||||
|
elif response.status == 400 and resp.get('error', {}).get('type') == 'invalid_request_error':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error testing model response: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def pretty_print_vertexai_keys(keys):
|
def pretty_print_vertexai_keys(keys):
|
||||||
print('-' * 90)
|
print('-' * 90)
|
||||||
print(f'Validated {len(keys)} Google Vertex AI keys:')
|
print(f'Validated {len(keys)} Google Vertex AI keys:')
|
||||||
for key in keys:
|
|
||||||
|
keys_with_opus = [key for key in keys if key.has_opus]
|
||||||
|
keys_without_opus = [key for key in keys if not key.has_opus]
|
||||||
|
|
||||||
|
print(f'\nValid keys with Opus enabled: {len(keys_with_opus)}')
|
||||||
|
for key in keys_with_opus:
|
||||||
|
print(f'{key.api_key} | {key.project_id} | has opus')
|
||||||
|
|
||||||
|
print(f'\nValid keys without Opus enabled: {len(keys_without_opus)}')
|
||||||
|
for key in keys_without_opus:
|
||||||
print(f'{key.api_key} | {key.project_id}')
|
print(f'{key.api_key} | {key.project_id}')
|
||||||
print(f'\n--- Total Valid Google Vertex AI Keys: {len(keys)} ---\n')
|
|
||||||
|
print(f'\n--- Total Valid Google Vertex AI Keys: {len(keys)} ({len(keys_with_opus)} with Opus enabled) ---\n')
|
||||||
|
|||||||
@@ -171,13 +171,14 @@ def validate_azure(key: APIKey):
|
|||||||
api_keys.add(key)
|
api_keys.add(key)
|
||||||
|
|
||||||
|
|
||||||
def validate_vertexai(key: APIKey):
|
async def validate_vertexai(key: APIKey, sem):
|
||||||
IO.conditional_print(f"Checking Vertex AI keyfile: {key.api_key}", args.verbose)
|
async with sem, aiohttp.ClientSession() as session:
|
||||||
if check_vertexai(key) is None:
|
IO.conditional_print(f"Checking VertexAI keyfile: {key.api_key}", args.verbose)
|
||||||
IO.conditional_print(f"Invalid Vertex AI keyfile: {key.api_key}", args.verbose)
|
if await check_vertexai(key, session) is None:
|
||||||
return
|
IO.conditional_print(f"Invalid VertexAI keyfile: {key.api_key}", args.verbose)
|
||||||
IO.conditional_print(f"Vertex AI keyfile '{key.api_key}' is valid", args.verbose)
|
return
|
||||||
api_keys.add(key)
|
IO.conditional_print(f"VertexAI keyfile '{key.api_key}' is valid", args.verbose)
|
||||||
|
api_keys.add(key)
|
||||||
|
|
||||||
|
|
||||||
async def execute_with_retries(func, key, sem, retries):
|
async def execute_with_retries(func, key, sem, retries):
|
||||||
@@ -222,7 +223,7 @@ async def validate_keys():
|
|||||||
if not os.path.isfile(key):
|
if not os.path.isfile(key):
|
||||||
continue
|
continue
|
||||||
key_obj = APIKey(Provider.VERTEXAI, key)
|
key_obj = APIKey(Provider.VERTEXAI, key)
|
||||||
futures.append(executor.submit(validate_vertexai, key_obj))
|
tasks.append(execute_with_retries(validate_vertexai, key_obj, concurrent_connections, 5))
|
||||||
elif "sk-ant-" in key[:7]:
|
elif "sk-ant-" in key[:7]:
|
||||||
match = anthropic_regex.match(key) if "ant-api03" in key else anthropic_secondary_regex.match(key)
|
match = anthropic_regex.match(key) if "ant-api03" in key else anthropic_secondary_regex.match(key)
|
||||||
if not match:
|
if not match:
|
||||||
@@ -290,7 +291,7 @@ def get_invalid_keys(valid_oai_keys, valid_anthropic_keys, valid_ai21_keys, vali
|
|||||||
valid_makersuite_keys_set = set([key.api_key for key in valid_makersuite_keys])
|
valid_makersuite_keys_set = set([key.api_key for key in valid_makersuite_keys])
|
||||||
valid_aws_keys_set = set([key.api_key for key in valid_aws_keys])
|
valid_aws_keys_set = set([key.api_key for key in valid_aws_keys])
|
||||||
valid_azure_keys_set = set([key.api_key for key in valid_azure_keys])
|
valid_azure_keys_set = set([key.api_key for key in valid_azure_keys])
|
||||||
valid_vertexai_keys_set = set([key.api_key for key in valid_vertexai_keys])
|
valid_vertexai_keys_set = set([f'"{key.api_key}"' for key in valid_vertexai_keys])
|
||||||
valid_mistral_keys_set = set([key.api_key for key in valid_mistral_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_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])
|
valid_elevenlabs_set = set([key.api_key for key in valid_elevenlabs_keys])
|
||||||
|
|||||||
Reference in New Issue
Block a user