Spaces:
Runtime error
Runtime error
Update main.py
Browse files
main.py
CHANGED
|
@@ -18,52 +18,141 @@ app.add_middleware(
|
|
| 18 |
)
|
| 19 |
|
| 20 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 21 |
-
#
|
| 22 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
-
PROVIDER_2_NAME = "deepseek"
|
| 38 |
-
PROVIDER_2_APIKEY = "sk-yyyy"
|
| 39 |
-
PROVIDER_2_BASEURL = "https://api.deepseek.com/v1"
|
| 40 |
-
PROVIDER_2_MODELS = "deepseek-chat,deepseek-coder"
|
| 41 |
|
| 42 |
-
|
| 43 |
-
"""
|
| 44 |
|
| 45 |
-
# โโ ่ฏปๅ API Keys โโ
|
| 46 |
raw_keys = os.getenv("API_KEYS", "")
|
| 47 |
-
api_keys = set(
|
| 48 |
-
k.strip() for k in raw_keys.split(",") if k.strip()
|
| 49 |
-
)
|
| 50 |
|
| 51 |
-
# โ
|
| 52 |
providers = {}
|
| 53 |
-
for
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
"api_key": api_key,
|
| 64 |
-
"base_url": baseurl.rstrip("/"),
|
| 65 |
-
"models": [m.strip() for m in models.split(",") if m.strip()],
|
| 66 |
}
|
|
|
|
| 67 |
|
| 68 |
logger.info(f"โ
ๅ ่ฝฝไบ {len(api_keys)} ไธช API Key")
|
| 69 |
logger.info(f"โ
ๅ ่ฝฝไบ {len(providers)} ไธช Provider: {list(providers.keys())}")
|
|
@@ -71,7 +160,6 @@ def load_config():
|
|
| 71 |
return api_keys, providers
|
| 72 |
|
| 73 |
|
| 74 |
-
# ๅฏๅจๆถๅ ่ฝฝไธๆฌก
|
| 75 |
API_KEYS, PROVIDERS = load_config()
|
| 76 |
|
| 77 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -114,7 +202,6 @@ async def chat_completions(
|
|
| 114 |
model = body.get("model", "")
|
| 115 |
provider = None
|
| 116 |
|
| 117 |
-
# ๆพๅฐๆฏๆ่ฏฅ model ็ provider
|
| 118 |
for p_cfg in PROVIDERS.values():
|
| 119 |
if model in p_cfg["models"]:
|
| 120 |
provider = p_cfg
|
|
@@ -126,7 +213,6 @@ async def chat_completions(
|
|
| 126 |
detail=f"ๆฒกๆ Provider ๆฏๆๆจกๅ: {model}"
|
| 127 |
)
|
| 128 |
|
| 129 |
-
# ่ฝฌๅๅฐไธๆธธ
|
| 130 |
async with httpx.AsyncClient(timeout=60) as client:
|
| 131 |
resp = await client.post(
|
| 132 |
f"{provider['base_url']}/chat/completions",
|
|
@@ -136,9 +222,10 @@ async def chat_completions(
|
|
| 136 |
return resp.json()
|
| 137 |
|
| 138 |
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
|
|
|
| 142 |
|
| 143 |
if __name__ == "__main__":
|
| 144 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
|
| 18 |
)
|
| 19 |
|
| 20 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 21 |
+
# ่ฏปๅๅ้กน็ฎๅบๅฎๅฝๅ็ Secrets
|
| 22 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 23 |
|
| 24 |
+
# ๅ้กน็ฎ็ Provider Key ๆ ๅฐ่กจ
|
| 25 |
+
PROVIDER_MAP = {
|
| 26 |
+
"GOOGLE_API_KEY": "google",
|
| 27 |
+
"GROQ_API_KEY": "groq",
|
| 28 |
+
"GITHUB_TOKEN": "github",
|
| 29 |
+
"OPENROUTER_API_KEY": "openrouter",
|
| 30 |
+
"MISTRAL_API_KEY": "mistral",
|
| 31 |
+
"TOGETHER_API_KEY": "together",
|
| 32 |
+
"NVIDIA_API_KEY": "nvidia",
|
| 33 |
+
"COHERE_API_KEY": "cohere",
|
| 34 |
+
"HF_TOKEN": "huggingface",
|
| 35 |
+
"CEREBRAS_API_KEY": "cerebras",
|
| 36 |
+
"SAMBANOVA_API_KEY": "sambanova",
|
| 37 |
+
"CLOUDFLARE_API_TOKEN": "cloudflare",
|
| 38 |
+
"ZHIPU_API_KEY": "zhipu",
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
# Provider ๅฏนๅบ็ base_url ๅๆฏๆ็ๆจกๅ
|
| 42 |
+
PROVIDER_CONFIG = {
|
| 43 |
+
"google": {
|
| 44 |
+
"base_url": "https://generativelanguage.googleapis.com/v1beta/openai",
|
| 45 |
+
"models": [
|
| 46 |
+
"gemini-2.0-flash","gemini-2.0-flash-lite",
|
| 47 |
+
"gemini-1.5-pro","gemini-1.5-flash","gemini-1.5-flash-8b"
|
| 48 |
+
],
|
| 49 |
+
},
|
| 50 |
+
"groq": {
|
| 51 |
+
"base_url": "https://api.groq.com/openai/v1",
|
| 52 |
+
"models": [
|
| 53 |
+
"llama-3.3-70b-versatile","llama-3.1-8b-instant",
|
| 54 |
+
"llama3-70b-8192","llama3-8b-8192",
|
| 55 |
+
"mixtral-8x7b-32768","gemma2-9b-it"
|
| 56 |
+
],
|
| 57 |
+
},
|
| 58 |
+
"github": {
|
| 59 |
+
"base_url": "https://models.inference.ai.azure.com",
|
| 60 |
+
"models": [
|
| 61 |
+
"gpt-4o","gpt-4o-mini",
|
| 62 |
+
"Phi-3.5-mini-instruct","Phi-3.5-MoE-instruct",
|
| 63 |
+
"Meta-Llama-3.1-70B-Instruct","Meta-Llama-3.1-405B-Instruct"
|
| 64 |
+
],
|
| 65 |
+
},
|
| 66 |
+
"openrouter": {
|
| 67 |
+
"base_url": "https://openrouter.ai/api/v1",
|
| 68 |
+
"models": [
|
| 69 |
+
"mistralai/mistral-7b-instruct:free",
|
| 70 |
+
"meta-llama/llama-3.2-3b-instruct:free",
|
| 71 |
+
"google/gemma-3-1b-it:free",
|
| 72 |
+
"deepseek/deepseek-r1:free",
|
| 73 |
+
],
|
| 74 |
+
},
|
| 75 |
+
"mistral": {
|
| 76 |
+
"base_url": "https://api.mistral.ai/v1",
|
| 77 |
+
"models": [
|
| 78 |
+
"mistral-small-latest","mistral-large-latest",
|
| 79 |
+
"open-mistral-7b","open-mixtral-8x7b"
|
| 80 |
+
],
|
| 81 |
+
},
|
| 82 |
+
"together": {
|
| 83 |
+
"base_url": "https://api.together.xyz/v1",
|
| 84 |
+
"models": [
|
| 85 |
+
"meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
|
| 86 |
+
"meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
|
| 87 |
+
"mistralai/Mixtral-8x7B-Instruct-v0.1"
|
| 88 |
+
],
|
| 89 |
+
},
|
| 90 |
+
"nvidia": {
|
| 91 |
+
"base_url": "https://integrate.api.nvidia.com/v1",
|
| 92 |
+
"models": [
|
| 93 |
+
"meta/llama-3.1-70b-instruct",
|
| 94 |
+
"meta/llama-3.1-8b-instruct",
|
| 95 |
+
"mistralai/mixtral-8x7b-instruct"
|
| 96 |
+
],
|
| 97 |
+
},
|
| 98 |
+
"cohere": {
|
| 99 |
+
"base_url": "https://api.cohere.com/v2",
|
| 100 |
+
"models": ["command-r-plus","command-r","command"],
|
| 101 |
+
},
|
| 102 |
+
"huggingface": {
|
| 103 |
+
"base_url": "https://api-inference.huggingface.co/v1",
|
| 104 |
+
"models": [
|
| 105 |
+
"meta-llama/Llama-3.2-3B-Instruct",
|
| 106 |
+
"mistralai/Mistral-7B-Instruct-v0.3"
|
| 107 |
+
],
|
| 108 |
+
},
|
| 109 |
+
"cerebras": {
|
| 110 |
+
"base_url": "https://api.cerebras.ai/v1",
|
| 111 |
+
"models": ["llama3.1-8b","llama3.1-70b"],
|
| 112 |
+
},
|
| 113 |
+
"sambanova": {
|
| 114 |
+
"base_url": "https://api.sambanova.ai/v1",
|
| 115 |
+
"models": [
|
| 116 |
+
"Meta-Llama-3.1-8B-Instruct",
|
| 117 |
+
"Meta-Llama-3.1-70B-Instruct",
|
| 118 |
+
"Meta-Llama-3.1-405B-Instruct"
|
| 119 |
+
],
|
| 120 |
+
},
|
| 121 |
+
"cloudflare": {
|
| 122 |
+
"base_url": "https://api.cloudflare.com/client/v4/accounts/{}/ai/v1",
|
| 123 |
+
"models": [
|
| 124 |
+
"@cf/meta/llama-3.1-8b-instruct",
|
| 125 |
+
"@cf/mistral/mistral-7b-instruct-v0.1"
|
| 126 |
+
],
|
| 127 |
+
},
|
| 128 |
+
"zhipu": {
|
| 129 |
+
"base_url": "https://open.bigmodel.cn/api/paas/v4",
|
| 130 |
+
"models": ["glm-4-flash","glm-4","glm-3-turbo"],
|
| 131 |
+
},
|
| 132 |
+
}
|
| 133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
+
def load_config():
|
| 136 |
+
"""ไป็ฏๅขๅ้่ฏปๅๆๆ้
็ฝฎ"""
|
| 137 |
|
| 138 |
+
# โโ ่ฏปๅ็จๆท API Keys๏ผ็จไบ้ดๆ๏ผ โโ
|
| 139 |
raw_keys = os.getenv("API_KEYS", "")
|
| 140 |
+
api_keys = set(k.strip() for k in raw_keys.split(",") if k.strip())
|
|
|
|
|
|
|
| 141 |
|
| 142 |
+
# โ๏ฟฝ๏ฟฝ ่ฏปๅ Provider Keys โโ
|
| 143 |
providers = {}
|
| 144 |
+
for env_name, provider_name in PROVIDER_MAP.items():
|
| 145 |
+
key_value = os.getenv(env_name, "").strip()
|
| 146 |
+
if not key_value:
|
| 147 |
+
continue # ๆฒก้
็ฝฎ่ฏฅ Provider๏ผ่ทณ่ฟ
|
| 148 |
+
|
| 149 |
+
cfg = PROVIDER_CONFIG.get(provider_name, {})
|
| 150 |
+
providers[provider_name] = {
|
| 151 |
+
"api_key": key_value,
|
| 152 |
+
"base_url": cfg.get("base_url", ""),
|
| 153 |
+
"models": cfg.get("models", []),
|
|
|
|
|
|
|
|
|
|
| 154 |
}
|
| 155 |
+
logger.info(f"โ
ๅ ่ฝฝ Provider: {provider_name}")
|
| 156 |
|
| 157 |
logger.info(f"โ
ๅ ่ฝฝไบ {len(api_keys)} ไธช API Key")
|
| 158 |
logger.info(f"โ
ๅ ่ฝฝไบ {len(providers)} ไธช Provider: {list(providers.keys())}")
|
|
|
|
| 160 |
return api_keys, providers
|
| 161 |
|
| 162 |
|
|
|
|
| 163 |
API_KEYS, PROVIDERS = load_config()
|
| 164 |
|
| 165 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
|
| 202 |
model = body.get("model", "")
|
| 203 |
provider = None
|
| 204 |
|
|
|
|
| 205 |
for p_cfg in PROVIDERS.values():
|
| 206 |
if model in p_cfg["models"]:
|
| 207 |
provider = p_cfg
|
|
|
|
| 213 |
detail=f"ๆฒกๆ Provider ๆฏๆๆจกๅ: {model}"
|
| 214 |
)
|
| 215 |
|
|
|
|
| 216 |
async with httpx.AsyncClient(timeout=60) as client:
|
| 217 |
resp = await client.post(
|
| 218 |
f"{provider['base_url']}/chat/completions",
|
|
|
|
| 222 |
return resp.json()
|
| 223 |
|
| 224 |
|
| 225 |
+
@app.get("/health")
|
| 226 |
+
async def health():
|
| 227 |
+
return {"status": "ok"}
|
| 228 |
+
|
| 229 |
|
| 230 |
if __name__ == "__main__":
|
| 231 |
uvicorn.run(app, host="0.0.0.0", port=7860)
|