openai_api_key_status / vertexLib.py
prxyasd's picture
Update vertexLib.py
5249897 verified
raw
history blame
7.39 kB
import json
import time
import requests
import jwt
import asyncio
# ─────────────────────────────────────────
# 1. GCP μ„œλΉ„μŠ€κ³„μ • μ•‘μ„ΈμŠ€ 토큰
# ─────────────────────────────────────────
def get_access_token(client_email, private_key):
current_time = int(time.time())
expiration_time = current_time + 600 # 10 λΆ„
claims = {
"iss": client_email,
"scope": "https://www.googleapis.com/auth/cloud-platform",
"aud": "https://oauth2.googleapis.com/token",
"exp": expiration_time,
"iat": current_time,
}
try:
signed_jwt = jwt.encode(claims, private_key, algorithm="RS256")
except Exception as e:
return False, str(e)
response = requests.post(
"https://oauth2.googleapis.com/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": signed_jwt,
},
)
if response.status_code == 200:
return True, response.json()["access_token"]
return False, response.text
# ─────────────────────────────────────────
# 2. GCP refresh-token μ•‘μ„ΈμŠ€ 토큰
# ─────────────────────────────────────────
def get_access_token_refresh(client_id, client_secret, refresh_token):
token_url = "https://oauth2.googleapis.com/token"
data = {
"client_id": client_id,
"client_secret": client_secret,
"refresh_token": refresh_token,
"grant_type": "refresh_token",
}
resp = requests.post(token_url, data=data)
if resp.status_code == 200:
return True, resp.json()["access_token"]
return False, resp.text
# ─────────────────────────────────────────
# 3. Gemini λͺ¨λΈ λͺ©λ‘ (ν•„μš” μ‹œ 10κ°œκΉŒμ§€λ§Œ)
# ─────────────────────────────────────────
def get_gemini_models(key, max_return: int = 10):
url = (
"https://generativelanguage.googleapis.com/v1beta/models"
f"?key={key}&pageSize=1000"
)
resp = requests.get(url)
if resp.status_code != 200:
return ""
models = resp.json().get("models", [])
names = [m["name"].split("/")[1] for m in models]
if len(names) > max_return:
return names[:max_return] + [f"...(+{len(names)-max_return})"]
return names
# ─────────────────────────────────────────
# 4. Gemini ν‚€ 간단 μƒνƒœ 체크
# ─────────────────────────────────────────
def check_key_gemini_availability(key):
"""
λ°˜ν™˜κ°’: (bool, str)
β€’ True, 'ok' : 정상
β€’ False, 'exceed' : μ‚¬μš©λŸ‰/μΏΌν„° 초과
β€’ False, 'invalid' : 잘λͺ»λœ ν‚€/κΆŒν•œ μ—†μŒ
β€’ False, 'error' : 기타 였λ₯˜
"""
# 방법 1) λͺ¨λΈ λͺ©λ‘ μ‹œλ„
model_list = get_gemini_models(key, 1)
if model_list != "":
return True, "ok"
# 방법 2) 더미 μš”μ²­ μ‹œλ„
url = (
"https://generativelanguage.googleapis.com/v1beta/models/"
"gemini-1.5-flash:generateContent"
f"?key={key}"
)
payload = {
"contents": [{"role": "user", "parts": [{"text": ""}]}],
"generationConfig": {"maxOutputTokens": 0},
}
try:
resp = requests.post(url, headers={"Content-Type": "application/json"}, json=payload)
except Exception:
return False, "error"
if resp.status_code == 200:
return True, "ok"
err = resp.json().get("error", {})
code = err.get("code", 0)
status = err.get("status", "")
if status == "INVALID_ARGUMENT":
return True, "ok"
if code == 429 or status == "RESOURCE_EXHAUSTED":
return False, "exceed"
if code in (401, 403) or status in ("PERMISSION_DENIED", "UNAUTHENTICATED"):
return False, "invalid"
return False, "error"
# ─────────────────────────────────────────
# 5. Gemini μ‹€μ œ μš”μ²­ (ν•„μš” μ‹œ)
# ─────────────────────────────────────────
def send_gemini_request(key, payload, model: str = "gemini-1.5-flash"):
url = (
"https://generativelanguage.googleapis.com/v1beta/models/"
f"{model}:generateContent?key={key}"
)
resp = requests.post(url, headers={"Content-Type": "application/json"}, json=payload)
if resp.status_code == 200:
return True, resp.json()
return False, resp.text
# ─────────────────────────────────────────
# 6. Vertex AI (Anthropic) 비동기 μš”μ²­
# ─────────────────────────────────────────
async def send_gcp_request(
session,
project_id,
access_token,
payload,
region="us-east5",
model="claude-3-5-sonnet@20240620",
):
VERTEX_URL = (
f"https://{region}-aiplatform.googleapis.com/v1/projects/"
f"{project_id}/locations/{region}/publishers/anthropic/models/{model}:streamRawPredict"
)
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json; charset=utf-8",
}
async with session.post(url=VERTEX_URL, headers=headers, data=payload) as resp:
if resp.status != 200:
return json.loads(await resp.text())
return await resp.json()
# ─────────────────────────────────────────
# 7. 닀쀑 ν‚€ 간단 검사 μ˜ˆμ‹œ ν•¨μˆ˜
# ─────────────────────────────────────────
async def quick_check(keys: list[str]):
"""
인자둜 받은 킀듀을 Google Gemini 킀라고 κ°€μ •ν•˜κ³ 
(key, availability, status) 3-ν•„λ“œ 리슀트 λ°˜ν™˜.
ν•„μš”ν•˜λ‹€λ©΄ μ—¬κΈ°μ„œ λ‹€λ₯Έ ν΄λΌμš°λ“œ 체크 루틴을 ν˜ΈμΆœν•˜λ„λ‘ ν™•μž₯.
"""
results = []
for k in keys:
ok, st = check_key_gemini_availability(k.strip())
results.append({"key": k.strip(), "availability": ok, "status": st})
return results
# ─────────────────────────────────────────
# 8. 단독 μ‹€ν–‰ ν…ŒμŠ€νŠΈ
# ─────────────────────────────────────────
if __name__ == "__main__":
# μ˜ˆμ‹œ ν‚€ λͺ©λ‘ (각자 보유 ν‚€λ‘œ ꡐ체)
test_keys = [
"AIzaSyExampleINVALIDKEY_for_demo1",
"AIzaSyExampleINVALIDKEY_for_demo2",
]
# 동기 μ‹€ν–‰ μ˜ˆμ‹œ
final = asyncio.run(quick_check(test_keys))
print(json.dumps(final, indent=2, ensure_ascii=False))