FreeLLMAPI / main.py
javaeeduke's picture
Create main.py
b1ddb4f verified
Raw
History Blame
4.64 kB
from fastapi import FastAPI, HTTPException, Depends, Header
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import os
import logging
import httpx
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI(title="FreeLLMAPI")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ไปŽ็Žฏๅขƒๅ˜้‡่ฏปๅ–ๆ‰€ๆœ‰้…็ฝฎ๏ผˆ้‡ๅฏๆฐธไธไธขๅคฑ๏ผ‰
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
def load_config():
"""
Secrets ๆ ผๅผ็บฆๅฎš๏ผš
API Keys๏ผˆๅ…่ฎธ่ฎฟ้—ฎ็š„็”จๆˆท๏ผ‰:
API_KEYS = "key1,key2,key3"
Providers๏ผˆไธŠๆธธ LLM ๆœๅŠก๏ผ‰:
PROVIDER_1_NAME = "openai"
PROVIDER_1_APIKEY = "sk-xxxx"
PROVIDER_1_BASEURL = "https://api.openai.com/v1"
PROVIDER_1_MODELS = "gpt-4o,gpt-4o-mini"
PROVIDER_2_NAME = "deepseek"
PROVIDER_2_APIKEY = "sk-yyyy"
PROVIDER_2_BASEURL = "https://api.deepseek.com/v1"
PROVIDER_2_MODELS = "deepseek-chat,deepseek-coder"
# ๆœ€ๅคšๆ”ฏๆŒ 20 ไธช Provider
"""
# โ”€โ”€ ่ฏปๅ– API Keys โ”€โ”€
raw_keys = os.getenv("API_KEYS", "")
api_keys = set(
k.strip() for k in raw_keys.split(",") if k.strip()
)
# โ”€โ”€ ่ฏปๅ– Providers โ”€โ”€
providers = {}
for i in range(1, 21):
name = os.getenv(f"PROVIDER_{i}_NAME")
api_key = os.getenv(f"PROVIDER_{i}_APIKEY")
baseurl = os.getenv(f"PROVIDER_{i}_BASEURL")
models = os.getenv(f"PROVIDER_{i}_MODELS", "")
if not name or not api_key or not baseurl:
continue # ่ฏฅ็ผ–ๅทๆœช้…็ฝฎ๏ผŒ่ทณ่ฟ‡
providers[name] = {
"api_key": api_key,
"base_url": baseurl.rstrip("/"),
"models": [m.strip() for m in models.split(",") if m.strip()],
}
logger.info(f"โœ… ๅŠ ่ฝฝไบ† {len(api_keys)} ไธช API Key")
logger.info(f"โœ… ๅŠ ่ฝฝไบ† {len(providers)} ไธช Provider: {list(providers.keys())}")
return api_keys, providers
# ๅฏๅŠจๆ—ถๅŠ ่ฝฝไธ€ๆฌก
API_KEYS, PROVIDERS = load_config()
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ้‰ดๆƒ
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
def verify_api_key(authorization: str = Header(...)):
token = authorization.removeprefix("Bearer ").strip()
if token not in API_KEYS:
raise HTTPException(status_code=401, detail="Invalid API key")
return token
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ่ทฏ็”ฑ
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@app.get("/health")
async def health():
return {
"status": "ok",
"keys": len(API_KEYS),
"providers": list(PROVIDERS.keys()),
}
@app.get("/v1/models")
async def list_models(_: str = Depends(verify_api_key)):
data = []
for p_cfg in PROVIDERS.values():
for m in p_cfg["models"]:
data.append({"id": m, "object": "model"})
return {"object": "list", "data": data}
@app.post("/v1/chat/completions")
async def chat_completions(
body: dict,
_: str = Depends(verify_api_key)
):
model = body.get("model", "")
provider = None
# ๆ‰พๅˆฐๆ”ฏๆŒ่ฏฅ model ็š„ provider
for p_cfg in PROVIDERS.values():
if model in p_cfg["models"]:
provider = p_cfg
break
if not provider:
raise HTTPException(
status_code=404,
detail=f"ๆฒกๆœ‰ Provider ๆ”ฏๆŒๆจกๅž‹: {model}"
)
# ่ฝฌๅ‘ๅˆฐไธŠๆธธ
async with httpx.AsyncClient(timeout=60) as client:
resp = await client.post(
f"{provider['base_url']}/chat/completions",
headers={"Authorization": f"Bearer {provider['api_key']}"},
json=body,
)
return resp.json()
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ๅ…ฅๅฃ
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)