javaeeduke commited on
Commit
b78e2db
ยท
verified ยท
1 Parent(s): b1ddb4f

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +130 -43
main.py CHANGED
@@ -18,52 +18,141 @@ app.add_middleware(
18
  )
19
 
20
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
21
- # ไปŽ็Žฏๅขƒๅ˜้‡่ฏปๅ–ๆ‰€ๆœ‰้…็ฝฎ๏ผˆ้‡ๅฏๆฐธไธไธขๅคฑ๏ผ‰
22
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
23
 
24
- def load_config():
25
- """
26
- Secrets ๆ ผๅผ็บฆๅฎš๏ผš
27
-
28
- API Keys๏ผˆๅ…่ฎธ่ฎฟ้—ฎ็š„็”จๆˆท๏ผ‰:
29
- API_KEYS = "key1,key2,key3"
30
-
31
- Providers๏ผˆไธŠๆธธ LLM ๆœๅŠก๏ผ‰:
32
- PROVIDER_1_NAME = "openai"
33
- PROVIDER_1_APIKEY = "sk-xxxx"
34
- PROVIDER_1_BASEURL = "https://api.openai.com/v1"
35
- PROVIDER_1_MODELS = "gpt-4o,gpt-4o-mini"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- # ๆœ€ๅคšๆ”ฏๆŒ 20 ไธช Provider
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
- # โ”€โ”€ ่ฏปๅ– Providers โ”€โ”€
52
  providers = {}
53
- for i in range(1, 21):
54
- name = os.getenv(f"PROVIDER_{i}_NAME")
55
- api_key = os.getenv(f"PROVIDER_{i}_APIKEY")
56
- baseurl = os.getenv(f"PROVIDER_{i}_BASEURL")
57
- models = os.getenv(f"PROVIDER_{i}_MODELS", "")
58
-
59
- if not name or not api_key or not baseurl:
60
- continue # ่ฏฅ็ผ–ๅทๆœช้…็ฝฎ๏ผŒ่ทณ่ฟ‡
61
-
62
- providers[name] = {
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)