Spaces:
Running
Running
Update api_usage.py
Browse files- api_usage.py +284 -215
api_usage.py
CHANGED
@@ -13,7 +13,8 @@ import asyncio, aiohttp
|
|
13 |
import aiohttp
|
14 |
|
15 |
BASE_URL = 'https://api.openai.com/v1'
|
16 |
-
GPT_TYPES = ["gpt-3.5-turbo", "gpt-4", "gpt-4-32k", "gpt-4-32k-0314", "gpt-4o", "gpt-4-turbo"]
|
|
|
17 |
|
18 |
TOKEN_LIMIT_PER_TIER_TURBO = {
|
19 |
"free": 40000,
|
@@ -42,199 +43,12 @@ RPM_LIMIT_PER_BUILD_TIER_ANT = {
|
|
42 |
} # https://docs.anthropic.com/claude/reference/rate-limits
|
43 |
|
44 |
|
45 |
-
def get_headers(key, org_id
|
46 |
headers = {'Authorization': f'Bearer {key}'}
|
47 |
if org_id:
|
48 |
headers["OpenAI-Organization"] = org_id
|
49 |
return headers
|
50 |
|
51 |
-
def get_subscription(key, session, org_list):
|
52 |
-
has_gpt4 = False
|
53 |
-
has_gpt4_32k = False
|
54 |
-
has_gpt4_32k_0314 = False
|
55 |
-
default_org = ""
|
56 |
-
org_description = []
|
57 |
-
org = []
|
58 |
-
rpm = []
|
59 |
-
tpm = []
|
60 |
-
quota = []
|
61 |
-
list_models = []
|
62 |
-
list_models_avai = set()
|
63 |
-
|
64 |
-
for org_in in org_list:
|
65 |
-
if len(org_list) < 2: # mismatch_organization
|
66 |
-
headers = get_headers(key)
|
67 |
-
available_models = get_models(session, key)
|
68 |
-
else:
|
69 |
-
headers = get_headers(key, org_in['id'])
|
70 |
-
available_models = get_models(session, key, org_in['id'])
|
71 |
-
if org_in['id']:
|
72 |
-
if org_in['is_default']:
|
73 |
-
default_org = org_in['name']
|
74 |
-
org_description.append(f"{org_in['description']} (Created: {datetime.utcfromtimestamp(org_in['created'])} UTC" + (", personal)" if org_in['personal'] else ")"))
|
75 |
-
if 'No perm' in available_models:
|
76 |
-
available_models.extend(GPT_TYPES)
|
77 |
-
has_gpt4_32k = True if GPT_TYPES[2] in available_models else False
|
78 |
-
has_gpt4_32k_0314 = True if GPT_TYPES[3] in available_models else False
|
79 |
-
has_gpt4 = True if GPT_TYPES[1] in available_models else False
|
80 |
-
|
81 |
-
if has_gpt4_32k_0314 or has_gpt4_32k:
|
82 |
-
if org_in['id']:
|
83 |
-
org.append(f"{org_in['id']} ({org_in['name']}, {org_in['title']}, {org_in['role']})")
|
84 |
-
if has_gpt4_32k:
|
85 |
-
list_models_avai.update(GPT_TYPES)
|
86 |
-
if 'No perm' in available_models:
|
87 |
-
status_formated = format_status(GPT_TYPES, session, headers)
|
88 |
-
else:
|
89 |
-
status_formated = format_status([GPT_TYPES[2], GPT_TYPES[4], GPT_TYPES[5], GPT_TYPES[1], GPT_TYPES[0]], session, headers)
|
90 |
-
rpm.append(status_formated[0])
|
91 |
-
tpm.append(status_formated[1])
|
92 |
-
quota.append(status_formated[2])
|
93 |
-
if 'No perm' in available_models:
|
94 |
-
lst_string = ""
|
95 |
-
length = len(status_formated[3])
|
96 |
-
count = 1
|
97 |
-
for k, v in status_formated[3].items():
|
98 |
-
if v:
|
99 |
-
if count < length:
|
100 |
-
lst_string += f'{k}, '
|
101 |
-
continue
|
102 |
-
else:
|
103 |
-
lst_string += f' {k} '
|
104 |
-
if v == False:
|
105 |
-
list_models_avai.remove(k)
|
106 |
-
if k == GPT_TYPES[2]:
|
107 |
-
has_gpt4_32k = False
|
108 |
-
elif k == GPT_TYPES[1]:
|
109 |
-
has_gpt4 = False
|
110 |
-
elif k == GPT_TYPES[0]:
|
111 |
-
has_35 = False
|
112 |
-
elif k == GPT_TYPES[4]:
|
113 |
-
has_4o = False
|
114 |
-
count += 1
|
115 |
-
lst_string += '(No get model permission)'
|
116 |
-
#list_models.append(f"gpt-4-32k, gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo (No get model permission)")
|
117 |
-
list_models.append(lst_string)
|
118 |
-
else:
|
119 |
-
list_models.append(f"gpt-4-32k, gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo ({len(available_models)} total)")
|
120 |
-
else:
|
121 |
-
list_models_avai.update([GPT_TYPES[3], GPT_TYPES[1], GPT_TYPES[0]])
|
122 |
-
status_formated = format_status([GPT_TYPES[3], GPT_TYPES[4], GPT_TYPES[5], GPT_TYPES[1], GPT_TYPES[0]], session, headers)
|
123 |
-
rpm.append(status_formated[0])
|
124 |
-
tpm.append(status_formated[1])
|
125 |
-
quota.append(status_formated[2])
|
126 |
-
list_models.append(f"gpt-4-32k-0314, gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo ({len(available_models)} total)")
|
127 |
-
|
128 |
-
elif has_gpt4:
|
129 |
-
if org_in['id']:
|
130 |
-
org.append(f"{org_in['id']} ({org_in['name']}, {org_in['title']}, {org_in['role']})")
|
131 |
-
list_models_avai.update([GPT_TYPES[1], GPT_TYPES[0]])
|
132 |
-
status_formated = format_status([GPT_TYPES[4], GPT_TYPES[5], GPT_TYPES[1], GPT_TYPES[0]], session, headers)
|
133 |
-
rpm.append(status_formated[0])
|
134 |
-
tpm.append(status_formated[1])
|
135 |
-
quota.append(status_formated[2])
|
136 |
-
list_models.append(f"gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo ({len(available_models)} total)")
|
137 |
-
|
138 |
-
else:
|
139 |
-
if org_in['id']:
|
140 |
-
org.append(f"{org_in['id']} ({org_in['name']}, {org_in['title']}, {org_in['role']})")
|
141 |
-
list_models_avai.update([GPT_TYPES[0]])
|
142 |
-
status_formated = format_status([GPT_TYPES[0]], session, headers)
|
143 |
-
rpm.append(status_formated[0])
|
144 |
-
tpm.append(status_formated[1])
|
145 |
-
quota.append(status_formated[2])
|
146 |
-
list_models.append(f"gpt-3.5-turbo ({len(available_models)} total)")
|
147 |
-
|
148 |
-
return {"has_gpt4_32k": True if GPT_TYPES[2] in list_models_avai else False,
|
149 |
-
"has_gpt4": True if GPT_TYPES[1] in list_models_avai else False,
|
150 |
-
"default_org": default_org,
|
151 |
-
"organization": [o for o in org],
|
152 |
-
"org_description": org_description,
|
153 |
-
"models": list_models,
|
154 |
-
"rpm": rpm,
|
155 |
-
"tpm": tpm,
|
156 |
-
"quota": quota}
|
157 |
-
|
158 |
-
def send_oai_completions(oai_stuff):
|
159 |
-
session = oai_stuff[0]
|
160 |
-
headers = oai_stuff[1]
|
161 |
-
model = oai_stuff[2]
|
162 |
-
model_status = False
|
163 |
-
try:
|
164 |
-
req_body = {"model": model, "max_tokens": 1}
|
165 |
-
rpm_string = ""
|
166 |
-
tpm_string = ""
|
167 |
-
quota_string = ""
|
168 |
-
r = session.post(f"{BASE_URL}/chat/completions", headers=headers, json=req_body, timeout=10)
|
169 |
-
result = r.json()
|
170 |
-
if "error" in result:
|
171 |
-
e = result.get("error", {}).get("code", "")
|
172 |
-
if e == None or e == 'missing_required_parameter':
|
173 |
-
rpm_num = int(r.headers.get("x-ratelimit-limit-requests", 0))
|
174 |
-
model_status = True
|
175 |
-
tpm_num = int(r.headers.get('x-ratelimit-limit-tokens', 0))
|
176 |
-
tpm_left = int(r.headers.get('x-ratelimit-remaining-tokens', 0))
|
177 |
-
_rpm = '{:,}'.format(rpm_num).replace(',', ' ')
|
178 |
-
_tpm = '{:,}'.format(tpm_num).replace(',', ' ')
|
179 |
-
_tpm_left = '{:,}'.format(tpm_left).replace(',', ' ')
|
180 |
-
rpm_string = f"{_rpm} ({model})"
|
181 |
-
#tpm_string = f"{_tpm} ({_tpm_left} left, {model})"
|
182 |
-
tpm_string = f"{_tpm} ({model})"
|
183 |
-
dictCount = 0
|
184 |
-
dictLength = len(TOKEN_LIMIT_PER_TIER_GPT4)
|
185 |
-
|
186 |
-
# Check if gpt-4 has custom tpm (600k for example), if not, proceed with 3turbo's tpm
|
187 |
-
if model == GPT_TYPES[1]:
|
188 |
-
for k, v in TOKEN_LIMIT_PER_TIER_GPT4.items():
|
189 |
-
if tpm_num == v:
|
190 |
-
break
|
191 |
-
else:
|
192 |
-
dictCount+=1
|
193 |
-
if dictCount == dictLength:
|
194 |
-
quota_string = "yes | custom-tier"
|
195 |
-
elif model == GPT_TYPES[0] and quota_string == "":
|
196 |
-
quota_string = check_key_tier(rpm_num, tpm_num, TOKEN_LIMIT_PER_TIER_TURBO, headers)
|
197 |
-
else:
|
198 |
-
rpm_string = f"0 ({model})"
|
199 |
-
tpm_string = f"0 ({model})"
|
200 |
-
quota_string = e
|
201 |
-
return rpm_string, tpm_string, quota_string, model, model_status
|
202 |
-
except Exception as e:
|
203 |
-
#print(e)
|
204 |
-
return "", "", "", model, model_status
|
205 |
-
|
206 |
-
def format_status(list_models_avai, session, headers):
|
207 |
-
rpm = []
|
208 |
-
tpm = []
|
209 |
-
model_status = {}
|
210 |
-
quota = ""
|
211 |
-
args = [(session, headers, model) for model in list_models_avai]
|
212 |
-
with concurrent.futures.ThreadPoolExecutor() as executer:
|
213 |
-
for result in executer.map(send_oai_completions, args):
|
214 |
-
rpm.append(result[0])
|
215 |
-
tpm.append(result[1])
|
216 |
-
model_status[result[3]] = result[4]
|
217 |
-
if result[2]:
|
218 |
-
if quota == 'yes | custom-tier':
|
219 |
-
continue
|
220 |
-
else:
|
221 |
-
quota = result[2]
|
222 |
-
rpm_str = ""
|
223 |
-
tpm_str = ""
|
224 |
-
for i in range(len(rpm)):
|
225 |
-
rpm_str += rpm[i] + (" | " if i < len(rpm)-1 else "")
|
226 |
-
tpm_str += tpm[i] + (" | " if i < len(rpm)-1 else "")
|
227 |
-
return rpm_str, tpm_str, quota, model_status
|
228 |
-
|
229 |
-
def check_key_tier(rpm, tpm, dict, headers):
|
230 |
-
dictItemsCount = len(dict)
|
231 |
-
dictCount = 0
|
232 |
-
for k, v in dict.items():
|
233 |
-
if tpm == v:
|
234 |
-
return f"yes | {k}"
|
235 |
-
dictCount+=1
|
236 |
-
if (dictCount == dictItemsCount):
|
237 |
-
return "yes | custom-tier"
|
238 |
|
239 |
def get_orgs(session, key):
|
240 |
headers=get_headers(key)
|
@@ -242,33 +56,205 @@ def get_orgs(session, key):
|
|
242 |
rq = session.get(f"{BASE_URL}/organizations", headers=headers, timeout=10)
|
243 |
return 200, rq.json()['data']
|
244 |
except:
|
245 |
-
if rq.status_code == 403:
|
246 |
return 403, rq.json()['error']['message']
|
247 |
else:
|
248 |
return False, False
|
249 |
-
|
250 |
-
def
|
251 |
-
|
252 |
-
headers = get_headers(key, org)
|
253 |
-
else:
|
254 |
-
headers = get_headers(key)
|
255 |
-
|
256 |
try:
|
257 |
-
rq = session.get(f"{BASE_URL}/
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
except:
|
263 |
-
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
def check_key_availability(session, key):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
try:
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
|
273 |
async def fetch_ant(async_session, json_data):
|
274 |
url = 'https://api.anthropic.com/v1/messages'
|
@@ -347,8 +333,17 @@ async def check_key_ant_availability(key, claude_model):
|
|
347 |
tpm = ""
|
348 |
tpm_left = ""
|
349 |
tier = ""
|
350 |
-
|
|
|
|
|
|
|
|
|
351 |
async with aiohttp.ClientSession(headers=headers) as async_session:
|
|
|
|
|
|
|
|
|
|
|
352 |
async with async_session.post(url=url, json=json_data) as response:
|
353 |
result = await response.json()
|
354 |
if response.status == 200:
|
@@ -356,15 +351,19 @@ async def check_key_ant_availability(key, claude_model):
|
|
356 |
rpm_left = response.headers.get('anthropic-ratelimit-requests-remaining', '')
|
357 |
tpm = response.headers.get('anthropic-ratelimit-tokens-limit', '')
|
358 |
tpm_left = response.headers.get('anthropic-ratelimit-tokens-remaining', '')
|
|
|
|
|
|
|
|
|
359 |
tier = check_ant_tier(rpm)
|
360 |
msg = result.get('content', [''])[0].get('text', '')
|
361 |
-
return True, "Working", msg, rpm, rpm_left, tpm, tpm_left, tier
|
362 |
else:
|
363 |
#err_type = result.get('error', '').get('type', '')
|
364 |
err_msg = result.get('error', '').get('message', '')
|
365 |
if response.status == 401:
|
366 |
-
return False, f'Error: {response.status}', err_msg, rpm, rpm_left, tpm, tpm_left, tier
|
367 |
-
return True, f'Error: {response.status}', err_msg, rpm, rpm_left, tpm, tpm_left, tier
|
368 |
|
369 |
def check_key_gemini_availability(key):
|
370 |
avai = False
|
@@ -642,7 +641,7 @@ def is_model_working(form_info, model_info):
|
|
642 |
return model_info['agreementAvailability']['errorMessage']
|
643 |
return "No"
|
644 |
except:
|
645 |
-
return "
|
646 |
|
647 |
async def get_model_status(session, key, secret, region, model_name, form_info):
|
648 |
model_info = await bedrock_model_available(session, key, secret, region, f"anthropic.{model_name}")
|
@@ -686,7 +685,7 @@ async def check_bedrock_claude_status(session, key, secret):
|
|
686 |
if region and model_name:
|
687 |
if msg == "Maybe":
|
688 |
invoke_info = await send_signed_request_bedrock(session, payload, f"anthropic.{model_name}", key, secret, region)
|
689 |
-
if 'messages.0' in invoke_info.get('message') or 'many requests' in invoke_info.get('message'):
|
690 |
models[model_name].append(f'{region}')
|
691 |
else:
|
692 |
models[model_name].append(region)
|
@@ -883,6 +882,76 @@ def check_elevenlabs_status(key):
|
|
883 |
else:
|
884 |
return False, user_info[1], ""
|
885 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
886 |
if __name__ == "__main__":
|
887 |
key = os.getenv("OPENAI_API_KEY")
|
888 |
key_ant = os.getenv("ANTHROPIC_API_KEY")
|
|
|
13 |
import aiohttp
|
14 |
|
15 |
BASE_URL = 'https://api.openai.com/v1'
|
16 |
+
GPT_TYPES = ["gpt-3.5-turbo", "gpt-4", "gpt-4-32k", "gpt-4-32k-0314", "gpt-4o", "gpt-4-turbo", "chatgpt-4o-latest" ]
|
17 |
+
GPT_TYPES_ORDER = ["gpt-4-32k", "gpt-4-32k-0314", "chatgpt-4o-latest", "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"]
|
18 |
|
19 |
TOKEN_LIMIT_PER_TIER_TURBO = {
|
20 |
"free": 40000,
|
|
|
43 |
} # https://docs.anthropic.com/claude/reference/rate-limits
|
44 |
|
45 |
|
46 |
+
def get_headers(key, org_id=None):
|
47 |
headers = {'Authorization': f'Bearer {key}'}
|
48 |
if org_id:
|
49 |
headers["OpenAI-Organization"] = org_id
|
50 |
return headers
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
def get_orgs(session, key):
|
54 |
headers=get_headers(key)
|
|
|
56 |
rq = session.get(f"{BASE_URL}/organizations", headers=headers, timeout=10)
|
57 |
return 200, rq.json()['data']
|
58 |
except:
|
59 |
+
if rq.status_code == 403 or (rq.status_code == 401 and 'insufficient permissions' in f'{rq.text}'):
|
60 |
return 403, rq.json()['error']['message']
|
61 |
else:
|
62 |
return False, False
|
63 |
+
|
64 |
+
def get_orgs_me(session, key):
|
65 |
+
headers=get_headers(key)
|
|
|
|
|
|
|
|
|
66 |
try:
|
67 |
+
rq = session.get(f"{BASE_URL}/me", headers=headers, timeout=10)
|
68 |
+
if rq.status_code == 200:
|
69 |
+
return 200, rq.json()['orgs']['data']
|
70 |
+
else:
|
71 |
+
return rq.status_code, ""
|
72 |
except:
|
73 |
+
return False, rq.json()['error']['message']
|
74 |
+
|
75 |
+
def get_models(session, key, org_id=None):
|
76 |
+
headers = get_headers(key, org_id)
|
77 |
+
try:
|
78 |
+
response = session.get(f"{BASE_URL}/models", headers=headers, timeout=10)
|
79 |
+
response.raise_for_status()
|
80 |
+
all_models = response.json().get("data", [])
|
81 |
+
available_models = [model["id"] for model in all_models]
|
82 |
+
return available_models, all_models
|
83 |
+
except requests.exceptions.RequestException:
|
84 |
+
if response.status_code == 403:
|
85 |
+
return ['No perm'], []
|
86 |
+
return [], []
|
87 |
+
|
88 |
+
|
89 |
def check_key_availability(session, key):
|
90 |
+
return get_orgs(session, key)
|
91 |
+
|
92 |
+
def get_subscription(key, session, org_data):
|
93 |
+
default_org = ""
|
94 |
+
org_description = []
|
95 |
+
organizations = []
|
96 |
+
rpm_list = []
|
97 |
+
tpm_list = []
|
98 |
+
quota_list = []
|
99 |
+
models_list = []
|
100 |
+
int_models = []
|
101 |
+
all_models = []
|
102 |
+
has_gpt4 = False
|
103 |
+
has_gpt4_32k = False
|
104 |
+
|
105 |
+
if isinstance(org_data, str):
|
106 |
+
organizations.append(org_data)
|
107 |
+
org_list = [{"id": ""}]
|
108 |
+
else:
|
109 |
+
org_list = org_data
|
110 |
+
#print(org_list)
|
111 |
+
for org in org_list:
|
112 |
+
org_id = org.get('id')
|
113 |
+
headers = get_headers(key, org_id)
|
114 |
+
all_available_models_info = get_models(session, key, org_id)
|
115 |
+
all_available_models = all_available_models_info[0]
|
116 |
+
available_models = [model for model in all_available_models if model in GPT_TYPES]
|
117 |
+
if 'No perm' in available_models:
|
118 |
+
available_models = GPT_TYPES
|
119 |
+
|
120 |
+
if org.get('is_default'):
|
121 |
+
default_org = org.get('name', '')
|
122 |
+
|
123 |
+
if org_id:
|
124 |
+
organizations.append(f"{org_id} ({org.get('name')}, {org.get('title')}, {org.get('role')})")
|
125 |
+
org_description.append(f"{org.get('description')} (Created: {datetime.utcfromtimestamp(org.get('created'))} UTC"
|
126 |
+
+ (", personal)" if org.get('personal') else ")"))
|
127 |
+
|
128 |
+
status = format_status(available_models, session, headers)
|
129 |
+
rpm_list.append(" | ".join(status["rpm"]))
|
130 |
+
tpm_list.append(" | ".join(status["tpm"]))
|
131 |
+
|
132 |
+
quota = determine_quota_for_org(status)
|
133 |
+
quota_list.append(quota)
|
134 |
+
|
135 |
+
models_list.append(", ".join(status["models"]) + f" ({len(all_available_models)} total)")
|
136 |
+
all_models.append(all_available_models)
|
137 |
+
|
138 |
+
has_gpt4 = has_gpt4 or GPT_TYPES[1] in available_models
|
139 |
+
has_gpt4_32k = has_gpt4_32k or GPT_TYPES[2] in available_models
|
140 |
+
|
141 |
+
return {
|
142 |
+
"has_gpt4": has_gpt4,
|
143 |
+
"has_gpt4_32k": has_gpt4_32k,
|
144 |
+
"default_org": default_org,
|
145 |
+
"organization": organizations,
|
146 |
+
"org_description": org_description,
|
147 |
+
"models": models_list,
|
148 |
+
"rpm": rpm_list,
|
149 |
+
"tpm": tpm_list,
|
150 |
+
"quota": quota_list,
|
151 |
+
"all_models": all_models
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
def determine_quota_for_org(status):
|
156 |
+
for model, quota in zip(status["models"], status["quota"]):
|
157 |
+
if model == "gpt-4":
|
158 |
+
if quota == "custom-tier":
|
159 |
+
return quota
|
160 |
+
|
161 |
+
for model, quota in zip(status["models"], status["quota"]):
|
162 |
+
if model == "gpt-3.5-turbo":
|
163 |
+
return quota
|
164 |
+
|
165 |
+
for quota in status["quota"]:
|
166 |
+
if quota not in ["unknown", "custom-tier"]:
|
167 |
+
return quota
|
168 |
+
|
169 |
+
return "unknown"
|
170 |
+
|
171 |
+
def format_status(models, session, headers):
|
172 |
+
rpm = []
|
173 |
+
tpm = []
|
174 |
+
quota = []
|
175 |
+
model_status = {}
|
176 |
+
|
177 |
+
args = [(session, headers, model) for model in models]
|
178 |
+
|
179 |
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
180 |
+
results = executor.map(lambda x: send_oai_completions(*x), args)
|
181 |
+
|
182 |
+
model_results = {result["model"]: result for result in results}
|
183 |
+
|
184 |
+
sorted_models = [model for model in GPT_TYPES_ORDER if model in model_results]
|
185 |
+
|
186 |
+
for model in sorted_models:
|
187 |
+
result = model_results[model]
|
188 |
+
rpm.append(result["rpm"])
|
189 |
+
tpm.append(result["tpm"])
|
190 |
+
quota.append(result["quota"])
|
191 |
+
model_status[model] = result["status"]
|
192 |
+
|
193 |
+
return {
|
194 |
+
"rpm": rpm,
|
195 |
+
"tpm": tpm,
|
196 |
+
"quota": quota,
|
197 |
+
"models": sorted_models,
|
198 |
+
"model_status": model_status
|
199 |
+
}
|
200 |
+
|
201 |
+
def send_oai_completions(session, headers, model):
|
202 |
try:
|
203 |
+
response = session.post(
|
204 |
+
f"{BASE_URL}/chat/completions",
|
205 |
+
headers=headers,
|
206 |
+
json={"model": model, "max_tokens": 1},
|
207 |
+
timeout=10
|
208 |
+
)
|
209 |
+
|
210 |
+
result = response.json()
|
211 |
+
rpm = int(response.headers.get("x-ratelimit-limit-requests", 0))
|
212 |
+
tpm = int(response.headers.get("x-ratelimit-limit-tokens", 0))
|
213 |
+
quota_string = ""
|
214 |
+
|
215 |
+
if "error" in result:
|
216 |
+
error_code = result.get("error", {}).get("code", "")
|
217 |
+
if error_code in [None, "missing_required_parameter"]:
|
218 |
+
quota_string = check_tier(tpm, TOKEN_LIMIT_PER_TIER_GPT4 if model == "gpt-4" else TOKEN_LIMIT_PER_TIER_TURBO)
|
219 |
+
return {
|
220 |
+
"rpm": f"{rpm:,} ({model})",
|
221 |
+
"tpm": f"{tpm:,} ({model})",
|
222 |
+
"quota": quota_string,
|
223 |
+
"model": model,
|
224 |
+
"status": True
|
225 |
+
}
|
226 |
+
else:
|
227 |
+
return {
|
228 |
+
"rpm": f"0 ({model})",
|
229 |
+
"tpm": f"0 ({model})",
|
230 |
+
"quota": error_code,
|
231 |
+
"model": model,
|
232 |
+
"status": False
|
233 |
+
}
|
234 |
+
|
235 |
+
quota_string = check_tier(tpm, TOKEN_LIMIT_PER_TIER_GPT4 if model == "gpt-4" else TOKEN_LIMIT_PER_TIER_TURBO)
|
236 |
+
return {
|
237 |
+
"rpm": f"{rpm:,} ({model})",
|
238 |
+
"tpm": f"{tpm:,} ({model})",
|
239 |
+
"quota": quota_string,
|
240 |
+
"model": model,
|
241 |
+
"status": True
|
242 |
+
}
|
243 |
+
|
244 |
+
except requests.exceptions.RequestException:
|
245 |
+
return {
|
246 |
+
"rpm": "0",
|
247 |
+
"tpm": "0",
|
248 |
+
"quota": "request_failed",
|
249 |
+
"model": model,
|
250 |
+
"status": False
|
251 |
+
}
|
252 |
+
|
253 |
+
def check_tier(tpm, token_limits):
|
254 |
+
for tier, limit in token_limits.items():
|
255 |
+
if tpm == limit:
|
256 |
+
return tier
|
257 |
+
return "custom-tier"
|
258 |
|
259 |
async def fetch_ant(async_session, json_data):
|
260 |
url = 'https://api.anthropic.com/v1/messages'
|
|
|
333 |
tpm = ""
|
334 |
tpm_left = ""
|
335 |
tier = ""
|
336 |
+
tpm_input = ""
|
337 |
+
tpm_input_left = ""
|
338 |
+
tpm_output = ""
|
339 |
+
tpm_output_left = ""
|
340 |
+
models = ""
|
341 |
async with aiohttp.ClientSession(headers=headers) as async_session:
|
342 |
+
async with async_session.get(url='https://api.anthropic.com/v1/models') as m_response:
|
343 |
+
if m_response.status == 200:
|
344 |
+
models_info = await m_response.json()
|
345 |
+
models = [model['id'] for model in models_info['data']]
|
346 |
+
|
347 |
async with async_session.post(url=url, json=json_data) as response:
|
348 |
result = await response.json()
|
349 |
if response.status == 200:
|
|
|
351 |
rpm_left = response.headers.get('anthropic-ratelimit-requests-remaining', '')
|
352 |
tpm = response.headers.get('anthropic-ratelimit-tokens-limit', '')
|
353 |
tpm_left = response.headers.get('anthropic-ratelimit-tokens-remaining', '')
|
354 |
+
tpm_input = response.headers.get('anthropic-ratelimit-input-tokens-limit', '')
|
355 |
+
tpm_input_left = response.headers.get('anthropic-ratelimit-input-tokens-remaining', '')
|
356 |
+
tpm_output = response.headers.get('anthropic-ratelimit-output-tokens-limit', '')
|
357 |
+
tpm_output_left = response.headers.get('anthropic-ratelimit-output-tokens-remaining', '')
|
358 |
tier = check_ant_tier(rpm)
|
359 |
msg = result.get('content', [''])[0].get('text', '')
|
360 |
+
return True, "Working", msg, rpm, rpm_left, tpm, tpm_left, tier, tpm_input, tpm_input_left, tpm_output, tpm_output_left, models
|
361 |
else:
|
362 |
#err_type = result.get('error', '').get('type', '')
|
363 |
err_msg = result.get('error', '').get('message', '')
|
364 |
if response.status == 401:
|
365 |
+
return False, f'Error: {response.status}', err_msg, rpm, rpm_left, tpm, tpm_left, tier, tpm_input, tpm_input_left, tpm_output, tpm_output_left, models
|
366 |
+
return True, f'Error: {response.status}', err_msg, rpm, rpm_left, tpm, tpm_left, tier, tpm_input, tpm_input_left, tpm_output, tpm_output_left, models
|
367 |
|
368 |
def check_key_gemini_availability(key):
|
369 |
avai = False
|
|
|
641 |
return model_info['agreementAvailability']['errorMessage']
|
642 |
return "No"
|
643 |
except:
|
644 |
+
return "Maybe"
|
645 |
|
646 |
async def get_model_status(session, key, secret, region, model_name, form_info):
|
647 |
model_info = await bedrock_model_available(session, key, secret, region, f"anthropic.{model_name}")
|
|
|
685 |
if region and model_name:
|
686 |
if msg == "Maybe":
|
687 |
invoke_info = await send_signed_request_bedrock(session, payload, f"anthropic.{model_name}", key, secret, region)
|
688 |
+
if 'messages.0' in invoke_info.get('message') or 'many requests' in invoke_info.get('message') or 'equal to 1' in invoke_info.get('message'):
|
689 |
models[model_name].append(f'{region}')
|
690 |
else:
|
691 |
models[model_name].append(region)
|
|
|
882 |
else:
|
883 |
return False, user_info[1], ""
|
884 |
|
885 |
+
def check_xai_status(key):
|
886 |
+
url = 'https://api.x.ai/v1/'
|
887 |
+
headers = {"authorization": f"Bearer {key}"}
|
888 |
+
response = requests.get(url+"api-key", headers=headers)
|
889 |
+
if response.status_code == 200:
|
890 |
+
response_models = requests.get(url+"models", headers=headers)
|
891 |
+
models = response_models.json()
|
892 |
+
if 'data' in models:
|
893 |
+
return True, response.json(), models['data']
|
894 |
+
return True, response.json(), models
|
895 |
+
else:
|
896 |
+
return False, response.json(), ""
|
897 |
+
|
898 |
+
def check_stripe_status(key):
|
899 |
+
response = requests.get('https://api.stripe.com/v1/balance', auth=(key, ''))
|
900 |
+
|
901 |
+
if response.status_code == 200:
|
902 |
+
return True, response.json()
|
903 |
+
else:
|
904 |
+
return False, response.json()
|
905 |
+
|
906 |
+
def check_stability_info(url, headers):
|
907 |
+
response = requests.get(url=url, headers=headers)
|
908 |
+
if response.status_code == 200:
|
909 |
+
return True, response.json()
|
910 |
+
else:
|
911 |
+
return False, response.json()
|
912 |
+
|
913 |
+
def check_stability_status(key):
|
914 |
+
headers = {"Authorization": f"Bearer {key}"}
|
915 |
+
|
916 |
+
status, account = check_stability_info('https://api.stability.ai/v1/user/account', headers)
|
917 |
+
|
918 |
+
if 'Incorrect API key' in f'{account}':
|
919 |
+
return False, account, "", ""
|
920 |
+
|
921 |
+
_, models = check_stability_info('https://api.stability.ai/v1/engines/list', headers)
|
922 |
+
_, credit = check_stability_info('https://api.stability.ai/v1/user/balance', headers)
|
923 |
+
|
924 |
+
return True, account, models, credit
|
925 |
+
|
926 |
+
def check_deepseek_balance(key):
|
927 |
+
url = 'https://api.deepseek.com/user/balance'
|
928 |
+
headers = {"Authorization": f"Bearer {key}"}
|
929 |
+
response = requests.get(url, headers=headers)
|
930 |
+
|
931 |
+
if response.status_code == 200:
|
932 |
+
return response.json()
|
933 |
+
else:
|
934 |
+
return ""
|
935 |
+
|
936 |
+
def check_deepseek_models(key):
|
937 |
+
url = 'https://api.deepseek.com/models'
|
938 |
+
headers = {"Authorization": f"Bearer {key}"}
|
939 |
+
response = requests.get(url, headers=headers)
|
940 |
+
|
941 |
+
if response.status_code == 200:
|
942 |
+
return True, response.json()['data']
|
943 |
+
else:
|
944 |
+
return False, response.json()
|
945 |
+
|
946 |
+
def check_deepseek_status(key):
|
947 |
+
status, models = check_deepseek_models(key)
|
948 |
+
if not status and 'no such user' in f'{models}':
|
949 |
+
return False, models, ""
|
950 |
+
|
951 |
+
balance_info = check_deepseek_balance(key)
|
952 |
+
|
953 |
+
return True, models, balance_info
|
954 |
+
|
955 |
if __name__ == "__main__":
|
956 |
key = os.getenv("OPENAI_API_KEY")
|
957 |
key_ant = os.getenv("ANTHROPIC_API_KEY")
|