openai_api_key_status / vertexLib.py
prxyasd's picture
Update vertexLib.py
bda97e5 verified
raw
history blame
6.55 kB
import json
import time
import requests
import jwt
# ─────────────────────────────────────────
# 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, 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"]
else:
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",
}
response = requests.post(token_url, data=data)
if response.status_code == 200:
return True, response.json()["access_token"]
else:
return False, response.text
# ─────────────────────────────────────────
# 3. (선택) λͺ¨λΈ λͺ©λ‘ 쑰회 – μ΅œλŒ€ 10개만 λ°˜ν™˜
# ─────────────────────────────────────────
def get_gemini_models(key, max_return: int = 1):
"""
λͺ¨λΈμ΄ λ„ˆλ¬΄ λ§Žμ•„ 가독성이 λ–¨μ–΄μ§€λ―€λ‘œ,
기본적으둜 10κ°œκΉŒμ§€λ§Œ λ°˜ν™˜ν•˜κ³  λ‚˜λ¨Έμ§€λŠ” 개수둜 μš”μ•½.
"""
url = f"https://generativelanguage.googleapis.com/v1beta/models?key={key}&pageSize=1000"
response = requests.get(url)
if response.status_code != 200:
return ""
models = response.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 None
# ─────────────────────────────────────────
# 4. β€œλ”λ―Έβ€ μš”μ²­μœΌλ‘œ ν‚€ μƒνƒœλ§Œ νŒλ³„
# ─────────────────────────────────────────
def send_fake_gemini_request(key, model: str = "gemini-1.5-flash"):
"""
ν”„λ‘¬ν”„νŠΈλ₯Ό 빈 λ¬Έμžμ—΄λ‘œ 보내 κ°„λ‹¨νžˆ ν‚€ μœ νš¨μ„±μ„ 체크.
λ°˜ν™˜κ°’: error dict | '' | None
"""
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={key}"
payload = {
"contents": [{"role": "user", "parts": [{"text": ""}]}],
"generationConfig": {"maxOutputTokens": 0},
}
try:
resp = requests.post(url, headers={"Content-Type": "application/json"}, json=payload)
return resp.json().get("error", "")
except Exception:
return None
def check_key_gemini_availability(key):
"""
β–Ά λ°˜ν™˜: (bool, str)
β€’ (True, 'ok') : ν‚€ 유효, μ‚¬μš© κ°€λŠ₯
β€’ (False, 'exceed') : quota / rate-limit 초과
β€’ (False, 'invalid') : 잘λͺ»λœ ν‚€ ν˜Ήμ€ κΆŒν•œ μ—†μŒ
β€’ (False, 'error') : 기타 λ„€νŠΈμ›Œν¬/μ•Œ 수 μ—†λŠ” 였λ₯˜
"""
err = send_fake_gemini_request(key)
# λ„€νŠΈμ›Œν¬ μ‹€νŒ¨
if err is None:
return False, "error"
# μ—λŸ¬ ν•„λ“œκ°€ μ—†μœΌλ©΄ 정상
if err == "":
return True, "ok"
# μ—λŸ¬ 객체 뢄석
code = err.get("code", 0)
status = err.get("status", "")
# 빈 ν”„λ‘¬ν”„νŠΈ λ•Œλ¬Έμ— INVALID_ARGUMENTκ°€ λœ¨λŠ” 경우 β†’ ν‚€λŠ” 정상
if status == "INVALID_ARGUMENT":
return True, "ok"
# quota 초과
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 = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={key}"
resp = requests.post(url, headers={"Content-Type": "application/json"}, json=payload)
if resp.status_code == 200:
return True, resp.json()
else:
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 response:
if response.status != 200:
return json.loads(await response.text())
return await response.json()