bahi-bh commited on
Commit
b28ae29
Β·
verified Β·
1 Parent(s): 7e1c722

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -86
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import time
2
  import random
3
  import traceback
 
4
 
5
  from fastapi import FastAPI, HTTPException, Request
6
  from fastapi.middleware.cors import CORSMiddleware
@@ -15,9 +16,7 @@ from g4f.Provider import __providers__
15
  # =====================================================
16
 
17
  API_KEY = "sk-your-secret-key"
18
-
19
  MODEL = "gpt-4o-mini"
20
-
21
  MAX_RETRIES = 10
22
  TIMEOUT = 60
23
 
@@ -28,9 +27,7 @@ SAFE_PROVIDERS = []
28
  # =====================================================
29
 
30
  for provider in __providers__:
31
-
32
  try:
33
-
34
  name = provider.__name__.lower()
35
 
36
  if not getattr(provider, "working", False):
@@ -54,12 +51,10 @@ for provider in __providers__:
54
  continue
55
 
56
  SAFE_PROVIDERS.append(provider)
57
-
58
  except:
59
  pass
60
 
61
  random.shuffle(SAFE_PROVIDERS)
62
-
63
  print(f"[+] SAFE PROVIDERS: {len(SAFE_PROVIDERS)}")
64
 
65
  client = Client()
@@ -69,8 +64,8 @@ client = Client()
69
  # =====================================================
70
 
71
  app = FastAPI(
72
- title="Smart G4F Gateway",
73
- version="1.0"
74
  )
75
 
76
  # =====================================================
@@ -86,108 +81,81 @@ app.add_middleware(
86
  )
87
 
88
  # =====================================================
89
- # REQUEST MODEL
90
  # =====================================================
91
 
92
  class ChatRequest(BaseModel):
93
-
94
  prompt: str
95
 
96
  # =====================================================
97
- # API KEY
98
  # =====================================================
99
 
100
  def verify_api_key(request: Request):
101
-
102
- # x-api-key
103
  x_api_key = request.headers.get("x-api-key")
104
-
105
  if x_api_key == API_KEY:
106
  return
107
 
108
- # Authorization Bearer
109
  auth = request.headers.get("Authorization")
110
-
111
  if auth and auth.startswith("Bearer "):
112
-
113
  token = auth.replace("Bearer ", "").strip()
114
-
115
  if token == API_KEY:
116
  return
117
 
118
  raise HTTPException(
119
- status_code=403,
120
  detail="Invalid API Key"
121
  )
122
 
123
  # =====================================================
124
- # SMART G4F
125
  # =====================================================
126
 
127
  class SmartG4F:
128
-
129
  def __init__(self):
130
-
131
  self.good = []
132
  self.bad = {}
133
 
134
  def mark_bad(self, provider, cooldown=300):
135
-
136
  self.bad[provider.__name__] = time.time() + cooldown
137
 
138
  def is_bad(self, provider):
139
-
140
  until = self.bad.get(provider.__name__)
141
-
142
  if not until:
143
  return False
144
-
145
  return time.time() < until
146
 
147
- def ask(self, prompt):
148
-
149
  providers = SAFE_PROVIDERS.copy()
150
-
151
  random.shuffle(providers)
152
-
153
  last_error = None
154
 
155
  for provider in providers[:MAX_RETRIES]:
156
-
157
  try:
158
-
159
  if self.is_bad(provider):
160
  continue
161
 
162
  print(f"[+] TRYING: {provider.__name__}")
163
 
164
  response = client.chat.completions.create(
165
- model=MODEL,
166
  provider=provider,
167
- messages=[
168
- {
169
- "role": "user",
170
- "content": prompt
171
- }
172
- ],
173
  timeout=TIMEOUT
174
  )
175
 
176
  text = None
177
-
178
  try:
179
-
180
  text = response.choices[0].message.content
181
-
182
  except:
183
-
184
  text = str(response)
185
 
186
  if not text:
187
  continue
188
 
189
  self.good.append(provider.__name__)
190
-
191
  print(f"[+] SUCCESS: {provider.__name__}")
192
 
193
  return {
@@ -196,84 +164,138 @@ class SmartG4F:
196
  }
197
 
198
  except Exception as e:
199
-
200
  last_error = str(e)
201
-
202
  print(f"[-] FAILED: {provider.__name__}")
203
  print(traceback.format_exc())
204
-
205
  self.mark_bad(provider)
206
 
207
  raise Exception(last_error or "All providers failed")
208
 
209
- # =====================================================
210
- # INSTANCE
211
- # =====================================================
212
-
213
  smart = SmartG4F()
214
 
215
  # =====================================================
216
- # ROOT
217
  # =====================================================
218
 
219
  @app.get("/")
220
-
221
  async def root():
222
-
223
  return {
224
  "status": "online",
225
  "providers": len(SAFE_PROVIDERS),
226
- "api_key": True
 
227
  }
228
 
229
- # =====================================================
230
- # CHAT
231
- # =====================================================
232
-
233
- @app.post("/chat")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
- async def chat(request: Request, body: ChatRequest):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
 
 
 
237
  verify_api_key(request)
 
 
 
 
238
 
239
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
- result = smart.ask(body.prompt)
242
-
 
 
 
 
 
243
  return {
244
  "success": True,
245
  "provider": result["provider"],
246
  "response": result["response"]
247
  }
248
-
249
  except Exception as e:
250
-
251
- raise HTTPException(
252
- status_code=500,
253
- detail=str(e)
254
- )
255
 
256
  # =====================================================
257
  # RUN
258
  # =====================================================
259
 
260
  if __name__ == "__main__":
261
-
262
  print("""
263
-
264
- ╔══════════════════════════════╗
265
- β•‘ SMART G4F GATEWAY β•‘
266
- ╠══════════════════════════════╣
267
- β•‘ API KEY ENABLED β•‘
268
- β•‘ x-api-key supported β•‘
269
- β•‘ Bearer supported β•‘
270
- β•‘ /chat β•‘
271
- β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
272
-
 
273
  """)
274
-
275
- uvicorn.run(
276
- app,
277
- host="0.0.0.0",
278
- port=7860
279
- )
 
1
  import time
2
  import random
3
  import traceback
4
+ import uuid
5
 
6
  from fastapi import FastAPI, HTTPException, Request
7
  from fastapi.middleware.cors import CORSMiddleware
 
16
  # =====================================================
17
 
18
  API_KEY = "sk-your-secret-key"
 
19
  MODEL = "gpt-4o-mini"
 
20
  MAX_RETRIES = 10
21
  TIMEOUT = 60
22
 
 
27
  # =====================================================
28
 
29
  for provider in __providers__:
 
30
  try:
 
31
  name = provider.__name__.lower()
32
 
33
  if not getattr(provider, "working", False):
 
51
  continue
52
 
53
  SAFE_PROVIDERS.append(provider)
 
54
  except:
55
  pass
56
 
57
  random.shuffle(SAFE_PROVIDERS)
 
58
  print(f"[+] SAFE PROVIDERS: {len(SAFE_PROVIDERS)}")
59
 
60
  client = Client()
 
64
  # =====================================================
65
 
66
  app = FastAPI(
67
+ title="Smart G4F Gateway (Claude/OpenAI Compatible)",
68
+ version="2.0"
69
  )
70
 
71
  # =====================================================
 
81
  )
82
 
83
  # =====================================================
84
+ # REQUEST MODELS
85
  # =====================================================
86
 
87
  class ChatRequest(BaseModel):
 
88
  prompt: str
89
 
90
  # =====================================================
91
+ # API KEY VERIFICATION
92
  # =====================================================
93
 
94
  def verify_api_key(request: Request):
95
+ # x-api-key support (Used by Claude clients)
 
96
  x_api_key = request.headers.get("x-api-key")
 
97
  if x_api_key == API_KEY:
98
  return
99
 
100
+ # Authorization Bearer support (Used by OpenAI clients)
101
  auth = request.headers.get("Authorization")
 
102
  if auth and auth.startswith("Bearer "):
 
103
  token = auth.replace("Bearer ", "").strip()
 
104
  if token == API_KEY:
105
  return
106
 
107
  raise HTTPException(
108
+ status_code=401,
109
  detail="Invalid API Key"
110
  )
111
 
112
  # =====================================================
113
+ # SMART G4F LOGIC
114
  # =====================================================
115
 
116
  class SmartG4F:
 
117
  def __init__(self):
 
118
  self.good = []
119
  self.bad = {}
120
 
121
  def mark_bad(self, provider, cooldown=300):
 
122
  self.bad[provider.__name__] = time.time() + cooldown
123
 
124
  def is_bad(self, provider):
 
125
  until = self.bad.get(provider.__name__)
 
126
  if not until:
127
  return False
 
128
  return time.time() < until
129
 
130
+ def ask(self, messages, requested_model=MODEL):
 
131
  providers = SAFE_PROVIDERS.copy()
 
132
  random.shuffle(providers)
 
133
  last_error = None
134
 
135
  for provider in providers[:MAX_RETRIES]:
 
136
  try:
 
137
  if self.is_bad(provider):
138
  continue
139
 
140
  print(f"[+] TRYING: {provider.__name__}")
141
 
142
  response = client.chat.completions.create(
143
+ model=requested_model,
144
  provider=provider,
145
+ messages=messages,
 
 
 
 
 
146
  timeout=TIMEOUT
147
  )
148
 
149
  text = None
 
150
  try:
 
151
  text = response.choices[0].message.content
 
152
  except:
 
153
  text = str(response)
154
 
155
  if not text:
156
  continue
157
 
158
  self.good.append(provider.__name__)
 
159
  print(f"[+] SUCCESS: {provider.__name__}")
160
 
161
  return {
 
164
  }
165
 
166
  except Exception as e:
 
167
  last_error = str(e)
 
168
  print(f"[-] FAILED: {provider.__name__}")
169
  print(traceback.format_exc())
 
170
  self.mark_bad(provider)
171
 
172
  raise Exception(last_error or "All providers failed")
173
 
 
 
 
 
174
  smart = SmartG4F()
175
 
176
  # =====================================================
177
+ # ENDPOINTS
178
  # =====================================================
179
 
180
  @app.get("/")
 
181
  async def root():
 
182
  return {
183
  "status": "online",
184
  "providers": len(SAFE_PROVIDERS),
185
+ "api_key_required": True,
186
+ "endpoints": ["/v1/messages (Claude)", "/v1/chat/completions (OpenAI)", "/chat (Legacy)"]
187
  }
188
 
189
+ # 1. Claude API Format (Used by Claude Co-work)
190
+ @app.post("/v1/messages")
191
+ async def claude_messages(request: Request):
192
+ verify_api_key(request)
193
+ body = await request.json()
194
+
195
+ messages = body.get("messages", [])
196
+ system_prompt = body.get("system", "")
197
+ req_model = body.get("model", MODEL)
198
+
199
+ # Convert Anthropic format to standard messages list
200
+ g4f_messages = []
201
+ if system_prompt:
202
+ g4f_messages.append({"role": "system", "content": system_prompt})
203
+
204
+ for msg in messages:
205
+ content = msg.get("content", "")
206
+ # Handle complex content blocks if sent by Claude clients
207
+ if isinstance(content, list):
208
+ text_content = " ".join([c.get("text", "") for c in content if c.get("type") == "text"])
209
+ else:
210
+ text_content = content
211
+
212
+ g4f_messages.append({
213
+ "role": msg.get("role", "user"),
214
+ "content": text_content
215
+ })
216
 
217
+ try:
218
+ result = smart.ask(g4f_messages, req_model)
219
+
220
+ # Return exact Anthropic API structure
221
+ return {
222
+ "id": f"msg_{uuid.uuid4().hex}",
223
+ "type": "message",
224
+ "role": "assistant",
225
+ "model": req_model,
226
+ "content": [
227
+ {
228
+ "type": "text",
229
+ "text": result["response"]
230
+ }
231
+ ],
232
+ "stop_reason": "end_turn",
233
+ "stop_sequence": None,
234
+ "usage": {"input_tokens": 0, "output_tokens": 0}
235
+ }
236
+ except Exception as e:
237
+ raise HTTPException(status_code=500, detail=str(e))
238
 
239
+ # 2. OpenAI API Format (Alternative standard)
240
+ @app.post("/v1/chat/completions")
241
+ async def openai_chat(request: Request):
242
  verify_api_key(request)
243
+ body = await request.json()
244
+
245
+ messages = body.get("messages", [])
246
+ req_model = body.get("model", MODEL)
247
 
248
  try:
249
+ result = smart.ask(messages, req_model)
250
+
251
+ return {
252
+ "id": f"chatcmpl-{uuid.uuid4().hex}",
253
+ "object": "chat.completion",
254
+ "created": int(time.time()),
255
+ "model": req_model,
256
+ "choices": [{
257
+ "index": 0,
258
+ "message": {
259
+ "role": "assistant",
260
+ "content": result["response"]
261
+ },
262
+ "finish_reason": "stop"
263
+ }]
264
+ }
265
+ except Exception as e:
266
+ raise HTTPException(status_code=500, detail=str(e))
267
 
268
+ # 3. Legacy Custom Format (Your original endpoint)
269
+ @app.post("/chat")
270
+ async def chat(request: Request, body: ChatRequest):
271
+ verify_api_key(request)
272
+ try:
273
+ messages = [{"role": "user", "content": body.prompt}]
274
+ result = smart.ask(messages)
275
  return {
276
  "success": True,
277
  "provider": result["provider"],
278
  "response": result["response"]
279
  }
 
280
  except Exception as e:
281
+ raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
282
 
283
  # =====================================================
284
  # RUN
285
  # =====================================================
286
 
287
  if __name__ == "__main__":
 
288
  print("""
289
+ ╔════════════════════════════════════════╗
290
+ β•‘ SMART G4F GATEWAY (COMPATIBLE) β•‘
291
+ ╠════════════════════════════════════════╣
292
+ β•‘ API KEY ENABLED β•‘
293
+ β•‘ x-api-key supported β•‘
294
+ β•‘ Bearer supported β•‘
295
+ β•‘ Endpoints: β•‘
296
+ β•‘ - /v1/messages (Claude Co-work) β•‘
297
+ β•‘ - /v1/chat/completions (OpenAI) β•‘
298
+ β•‘ - /chat (Legacy) β•‘
299
+ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
300
  """)
301
+ uvicorn.run(app, host="0.0.0.0", port=7860)