FreeLLMAPI / main.py
javaeeduke's picture
Update main.py
493506d verified
Raw
History Blame
7.35 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=["*"],
)
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ่ฏปๅ–ๅŽŸ้กน็›ฎๅ›บๅฎšๅ‘ฝๅ็š„ Secrets
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# ๅŽŸ้กน็›ฎ็š„ Provider Key ๆ˜ ๅฐ„่กจ
PROVIDER_MAP = {
"GOOGLE_API_KEY": "google",
"GROQ_API_KEY": "groq",
"GITHUB_TOKEN": "github",
"OPENROUTER_API_KEY": "openrouter",
"MISTRAL_API_KEY": "mistral",
"TOGETHER_API_KEY": "together",
"NVIDIA_API_KEY": "nvidia",
"COHERE_API_KEY": "cohere",
"HF_TOKEN": "huggingface",
"CEREBRAS_API_KEY": "cerebras",
"SAMBANOVA_API_KEY": "sambanova",
"CLOUDFLARE_API_TOKEN": "cloudflare",
"ZHIPU_API_KEY": "zhipu",
}
# Provider ๅฏนๅบ”็š„ base_url ๅ’Œๆ”ฏๆŒ็š„ๆจกๅž‹
PROVIDER_CONFIG = {
"google": {
"base_url": "https://generativelanguage.googleapis.com/v1beta/openai",
"models": [
"gemini-2.0-flash","gemini-2.0-flash-lite",
"gemini-1.5-pro","gemini-1.5-flash","gemini-1.5-flash-8b"
],
},
"groq": {
"base_url": "https://api.groq.com/openai/v1",
"models": [
"llama-3.3-70b-versatile","llama-3.1-8b-instant",
"llama3-70b-8192","llama3-8b-8192",
"mixtral-8x7b-32768","gemma2-9b-it"
],
},
"github": {
"base_url": "https://models.inference.ai.azure.com",
"models": [
"gpt-4o","gpt-4o-mini",
"Phi-3.5-mini-instruct","Phi-3.5-MoE-instruct",
"Meta-Llama-3.1-70B-Instruct","Meta-Llama-3.1-405B-Instruct"
],
},
"openrouter": {
"base_url": "https://openrouter.ai/api/v1",
"models": [
"mistralai/mistral-7b-instruct:free",
"meta-llama/llama-3.2-3b-instruct:free",
"google/gemma-3-1b-it:free",
"deepseek/deepseek-r1:free",
],
},
"mistral": {
"base_url": "https://api.mistral.ai/v1",
"models": [
"mistral-small-latest","mistral-large-latest",
"open-mistral-7b","open-mixtral-8x7b"
],
},
"together": {
"base_url": "https://api.together.xyz/v1",
"models": [
"meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
"meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
"mistralai/Mixtral-8x7B-Instruct-v0.1"
],
},
"nvidia": {
"base_url": "https://integrate.api.nvidia.com/v1",
"models": [
"meta/llama-3.1-70b-instruct",
"meta/llama-3.1-8b-instruct",
"mistralai/mixtral-8x7b-instruct"
],
},
"cohere": {
"base_url": "https://api.cohere.com/v2",
"models": ["command-r-plus","command-r","command"],
},
"huggingface": {
"base_url": "https://api-inference.huggingface.co/v1",
"models": [
"meta-llama/Llama-3.2-3B-Instruct",
"mistralai/Mistral-7B-Instruct-v0.3"
],
},
"cerebras": {
"base_url": "https://api.cerebras.ai/v1",
"models": ["llama3.1-8b","llama3.1-70b"],
},
"sambanova": {
"base_url": "https://api.sambanova.ai/v1",
"models": [
"Meta-Llama-3.1-8B-Instruct",
"Meta-Llama-3.1-70B-Instruct",
"Meta-Llama-3.1-405B-Instruct"
],
},
"cloudflare": {
"base_url": "https://api.cloudflare.com/client/v4/accounts/{}/ai/v1",
"models": [
"@cf/meta/llama-3.1-8b-instruct",
"@cf/mistral/mistral-7b-instruct-v0.1"
],
},
"zhipu": {
"base_url": "https://open.bigmodel.cn/api/paas/v4",
"models": ["glm-4-flash","glm-4","glm-3-turbo"],
},
}
def load_config():
"""ไปŽ็Žฏๅขƒๅ˜้‡่ฏปๅ–ๆ‰€ๆœ‰้…็ฝฎ"""
# โ”€โ”€ ่ฏปๅ–็”จๆˆท API Keys๏ผˆ็”จไบŽ้‰ดๆƒ๏ผ‰ โ”€โ”€
raw_keys = os.getenv("API_KEYS", "")
api_keys = set(k.strip() for k in raw_keys.split(",") if k.strip())
# โ”€โ”€ ่ฏปๅ– Provider Keys โ”€โ”€
providers = {}
for env_name, provider_name in PROVIDER_MAP.items():
key_value = os.getenv(env_name, "").strip()
if not key_value:
continue # ๆฒก้…็ฝฎ่ฏฅ Provider๏ผŒ่ทณ่ฟ‡
cfg = PROVIDER_CONFIG.get(provider_name, {})
providers[provider_name] = {
"api_key": key_value,
"base_url": cfg.get("base_url", ""),
"models": cfg.get("models", []),
}
logger.info(f"โœ… ๅŠ ่ฝฝ Provider: {provider_name}")
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
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()
@app.get("/health")
async def health():
return {"status": "ok"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)