bahi-bh commited on
Commit
53c3e06
·
verified ·
1 Parent(s): 678887c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -107
app.py CHANGED
@@ -3,11 +3,13 @@ from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import StreamingResponse, JSONResponse
4
  from pydantic import BaseModel
5
  from typing import List
6
- import g4f
7
  import json
8
- import uuid
9
  import time
10
- import asyncio
 
 
 
11
 
12
  # =====================================================
13
  # CONFIG
@@ -21,7 +23,7 @@ API_KEY = "sk-your-secret-key"
21
 
22
  app = FastAPI(
23
  title="Universal AI Gateway",
24
- version="2.1.0"
25
  )
26
 
27
  # =====================================================
@@ -40,18 +42,6 @@ app.add_middleware(
40
  # MODELS
41
  # =====================================================
42
 
43
- MODELS = [
44
- "gpt-4o-mini",
45
- "gpt-4",
46
- "claude-3-haiku",
47
- "llama-3.1-70b",
48
- "mixtral-8x7b"
49
- ]
50
-
51
- # =====================================================
52
- # REQUEST MODELS
53
- # =====================================================
54
-
55
  class Message(BaseModel):
56
  role: str
57
  content: str
@@ -72,7 +62,10 @@ def verify_api_key(req: Request):
72
  auth = req.headers.get("Authorization")
73
 
74
  if not auth:
75
- return True
 
 
 
76
 
77
  if not auth.startswith("Bearer "):
78
  raise HTTPException(
@@ -88,7 +81,24 @@ def verify_api_key(req: Request):
88
  detail="Invalid API Key"
89
  )
90
 
91
- return True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  # =====================================================
94
  # ROOT
@@ -99,81 +109,55 @@ async def root():
99
 
100
  return {
101
  "status": "online",
102
- "provider": "Duck.ai"
 
103
  }
104
 
105
  # =====================================================
106
- # MODELS ENDPOINT
107
  # =====================================================
108
 
109
  @app.get("/v1/models")
110
  async def models():
111
 
112
- return {
113
- "object": "list",
114
- "data": [
115
- {
116
- "id": model,
117
- "object": "model",
118
- "created": int(time.time()),
119
- "owned_by": "duck.ai"
120
- }
121
- for model in MODELS
122
- ]
123
- }
124
-
125
- # =====================================================
126
- # STREAM GENERATOR
127
- # =====================================================
128
-
129
- async def generate_stream(model, messages):
130
 
131
  try:
132
 
133
- response = await asyncio.to_thread(
134
- g4f.ChatCompletion.create,
135
- model=model,
136
- provider=g4f.Provider.DuckDuckGo,
137
- messages=messages,
138
- stream=True
139
- )
140
 
141
- for chunk in response:
142
-
143
- if chunk:
144
-
145
- payload = {
146
- "id": f"chatcmpl-{uuid.uuid4().hex}",
147
- "object": "chat.completion.chunk",
148
- "created": int(time.time()),
149
- "model": model,
150
- "choices": [
151
- {
152
- "index": 0,
153
- "delta": {
154
- "content": str(chunk)
155
- },
156
- "finish_reason": None
157
- }
158
- ]
159
- }
160
 
161
- yield f"data: {json.dumps(payload)}\n\n"
 
 
 
 
 
162
 
163
- await asyncio.sleep(0)
164
 
165
- yield "data: [DONE]\n\n"
 
 
 
 
 
 
166
 
167
- except Exception as e:
168
 
169
- error_payload = {
170
- "error": {
171
- "message": str(e),
172
- "type": "server_error"
173
- }
174
- }
175
 
176
- yield f"data: {json.dumps(error_payload)}\n\n"
 
 
 
177
 
178
  # =====================================================
179
  # CHAT COMPLETIONS
@@ -196,19 +180,94 @@ async def chat_completions(
196
  ]
197
 
198
  # =================================================
199
- # STREAM
200
  # =================================================
201
 
202
  if body.stream:
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  return StreamingResponse(
205
- generate_stream(
206
- body.model,
207
- messages
208
- ),
209
  media_type="text/event-stream",
210
  headers={
211
  "Cache-Control": "no-cache",
 
212
  "X-Accel-Buffering": "no"
213
  }
214
  )
@@ -217,38 +276,53 @@ async def chat_completions(
217
  # NORMAL RESPONSE
218
  # =================================================
219
 
220
- try:
221
 
222
- response = await asyncio.to_thread(
223
- g4f.ChatCompletion.create,
224
- model=body.model,
225
- provider=g4f.Provider.DuckDuckGo,
226
- messages=messages
227
- )
228
 
229
- return JSONResponse({
230
- "id": f"chatcmpl-{uuid.uuid4().hex}",
231
- "object": "chat.completion",
232
- "created": int(time.time()),
233
- "model": body.model,
234
- "choices": [
235
- {
236
- "index": 0,
237
- "message": {
238
- "role": "assistant",
239
- "content": str(response)
240
- },
241
- "finish_reason": "stop"
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  }
243
- ]
244
- })
245
 
246
- except Exception as e:
247
 
248
- raise HTTPException(
249
- status_code=500,
250
- detail=str(e)
251
- )
 
 
 
 
252
 
253
  # =====================================================
254
  # RUN
 
3
  from fastapi.responses import StreamingResponse, JSONResponse
4
  from pydantic import BaseModel
5
  from typing import List
6
+ import asyncio
7
  import json
 
8
  import time
9
+ import uuid
10
+
11
+ import g4f
12
+ import g4f.models
13
 
14
  # =====================================================
15
  # CONFIG
 
23
 
24
  app = FastAPI(
25
  title="Universal AI Gateway",
26
+ version="3.0.0"
27
  )
28
 
29
  # =====================================================
 
42
  # MODELS
43
  # =====================================================
44
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  class Message(BaseModel):
46
  role: str
47
  content: str
 
62
  auth = req.headers.get("Authorization")
63
 
64
  if not auth:
65
+ raise HTTPException(
66
+ status_code=401,
67
+ detail="Missing Authorization Header"
68
+ )
69
 
70
  if not auth.startswith("Bearer "):
71
  raise HTTPException(
 
81
  detail="Invalid API Key"
82
  )
83
 
84
+ # =====================================================
85
+ # PROVIDERS
86
+ # =====================================================
87
+
88
+ def get_providers():
89
+
90
+ providers = []
91
+
92
+ if hasattr(g4f.Provider, "DuckDuckGo"):
93
+ providers.append(g4f.Provider.DuckDuckGo)
94
+
95
+ if hasattr(g4f.Provider, "Blackbox"):
96
+ providers.append(g4f.Provider.Blackbox)
97
+
98
+ if hasattr(g4f.Provider, "Free2GPT"):
99
+ providers.append(g4f.Provider.Free2GPT)
100
+
101
+ return providers
102
 
103
  # =====================================================
104
  # ROOT
 
109
 
110
  return {
111
  "status": "online",
112
+ "service": "Universal AI Gateway",
113
+ "version": "3.0.0"
114
  }
115
 
116
  # =====================================================
117
+ # MODELS
118
  # =====================================================
119
 
120
  @app.get("/v1/models")
121
  async def models():
122
 
123
+ data = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  try:
126
 
127
+ all_models = list(g4f.models._all_models)
 
 
 
 
 
 
128
 
129
+ for model_name in all_models:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ data.append({
132
+ "id": str(model_name),
133
+ "object": "model",
134
+ "created": int(time.time()),
135
+ "owned_by": "g4f"
136
+ })
137
 
138
+ except Exception:
139
 
140
+ fallback = [
141
+ "gpt-4o-mini",
142
+ "gpt-4",
143
+ "claude-3-haiku",
144
+ "llama-3.1-70b",
145
+ "mixtral-8x7b"
146
+ ]
147
 
148
+ for model_name in fallback:
149
 
150
+ data.append({
151
+ "id": model_name,
152
+ "object": "model",
153
+ "created": int(time.time()),
154
+ "owned_by": "g4f"
155
+ })
156
 
157
+ return {
158
+ "object": "list",
159
+ "data": data
160
+ }
161
 
162
  # =====================================================
163
  # CHAT COMPLETIONS
 
180
  ]
181
 
182
  # =================================================
183
+ # STREAMING
184
  # =================================================
185
 
186
  if body.stream:
187
 
188
+ async def generate_stream():
189
+
190
+ providers = get_providers()
191
+
192
+ last_error = None
193
+
194
+ for provider in providers:
195
+
196
+ try:
197
+
198
+ response = await asyncio.to_thread(
199
+ g4f.ChatCompletion.create,
200
+ model=body.model,
201
+ provider=provider,
202
+ messages=messages,
203
+ stream=True
204
+ )
205
+
206
+ for chunk in response:
207
+
208
+ if chunk:
209
+
210
+ payload = {
211
+ "id": f"chatcmpl-{uuid.uuid4().hex}",
212
+ "object": "chat.completion.chunk",
213
+ "created": int(time.time()),
214
+ "model": body.model,
215
+ "choices": [
216
+ {
217
+ "index": 0,
218
+ "delta": {
219
+ "content": str(chunk)
220
+ },
221
+ "finish_reason": None
222
+ }
223
+ ]
224
+ }
225
+
226
+ yield f"data: {json.dumps(payload)}\n\n"
227
+
228
+ await asyncio.sleep(0)
229
+
230
+ done_payload = {
231
+ "id": f"chatcmpl-{uuid.uuid4().hex}",
232
+ "object": "chat.completion.chunk",
233
+ "created": int(time.time()),
234
+ "model": body.model,
235
+ "choices": [
236
+ {
237
+ "index": 0,
238
+ "delta": {},
239
+ "finish_reason": "stop"
240
+ }
241
+ ]
242
+ }
243
+
244
+ yield f"data: {json.dumps(done_payload)}\n\n"
245
+
246
+ yield "data: [DONE]\n\n"
247
+
248
+ return
249
+
250
+ except Exception as e:
251
+
252
+ last_error = str(e)
253
+
254
+ continue
255
+
256
+ error_payload = {
257
+ "error": {
258
+ "message": last_error or "All providers failed",
259
+ "type": "server_error"
260
+ }
261
+ }
262
+
263
+ yield f"data: {json.dumps(error_payload)}\n\n"
264
+
265
  return StreamingResponse(
266
+ generate_stream(),
 
 
 
267
  media_type="text/event-stream",
268
  headers={
269
  "Cache-Control": "no-cache",
270
+ "Connection": "keep-alive",
271
  "X-Accel-Buffering": "no"
272
  }
273
  )
 
276
  # NORMAL RESPONSE
277
  # =================================================
278
 
279
+ providers = get_providers()
280
 
281
+ last_error = None
282
+
283
+ for provider in providers:
284
+
285
+ try:
 
286
 
287
+ response = await asyncio.to_thread(
288
+ g4f.ChatCompletion.create,
289
+ model=body.model,
290
+ provider=provider,
291
+ messages=messages
292
+ )
293
+
294
+ return JSONResponse({
295
+ "id": f"chatcmpl-{uuid.uuid4().hex}",
296
+ "object": "chat.completion",
297
+ "created": int(time.time()),
298
+ "model": body.model,
299
+ "choices": [
300
+ {
301
+ "index": 0,
302
+ "message": {
303
+ "role": "assistant",
304
+ "content": str(response)
305
+ },
306
+ "finish_reason": "stop"
307
+ }
308
+ ],
309
+ "usage": {
310
+ "prompt_tokens": 0,
311
+ "completion_tokens": 0,
312
+ "total_tokens": 0
313
  }
314
+ })
 
315
 
316
+ except Exception as e:
317
 
318
+ last_error = str(e)
319
+
320
+ continue
321
+
322
+ raise HTTPException(
323
+ status_code=500,
324
+ detail=last_error or "All providers failed"
325
+ )
326
 
327
  # =====================================================
328
  # RUN