bahi-bh commited on
Commit
ab33dd3
·
verified ·
1 Parent(s): 4aa2f1e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +204 -82
main.py CHANGED
@@ -1,102 +1,224 @@
1
- import os
2
- import json
3
- import g4f
4
- import logging
5
- import time
6
- from fastapi import FastAPI, HTTPException, Header, Request
7
- from fastapi.responses import StreamingResponse
8
- from fastapi.middleware.cors import CORSMiddleware
9
- from pydantic import BaseModel
10
- from typing import List, Optional
11
-
12
- # ---------------- Logging ----------------
13
- logging.basicConfig(level=logging.INFO)
14
- logger = logging.getLogger(__name__)
15
-
16
- app = FastAPI(title="G4F Dynamic API")
17
-
18
- app.add_middleware(
19
- CORSMiddleware,
20
- allow_origins=["*"],
21
- allow_credentials=False,
22
- allow_methods=["*"],
23
- allow_headers=["*"]
24
- )
25
 
26
  API_KEY = os.getenv("API_KEY", "your_fallback_secret")
27
 
28
- class ChatMessage(BaseModel):
29
- role: str
30
- content: str
31
 
32
- class ChatRequest(BaseModel):
33
- model: str # أزلنا القيمة الافتراضية لنجعل المستخدم يختار أو نعتمد على g4f.models.default
34
- messages: List[ChatMessage]
35
- stream: bool = False
36
- provider: Optional[str] = None
37
 
38
  def verify_key(auth: str):
39
- if not auth or not auth.startswith("Bearer "):
40
- raise HTTPException(status_code=401, detail="Invalid or missing Token")
41
- token = auth.split(" ")[1]
42
- if token != API_KEY:
43
- raise HTTPException(status_code=401, detail="Unauthorized")
44
-
45
- @app.get("/v1/models")
46
- async def list_models(authorization: str = Header(None)):
47
- verify_key(authorization)
48
- # استخراج كافة النماذج المتوفرة في الإصدار الحالي للمكتبة
49
- model_list = sorted(g4f.models._all)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  return {
51
- "object": "list",
52
- "data": [{"id": m, "object": "model", "owned_by": "g4f"} for m in model_list]
 
 
 
53
  }
54
 
55
- @app.post("/v1/chat/completions")
56
- async def chat(body: ChatRequest, authorization: str = Header(None)):
57
- verify_key(authorization)
58
-
59
- try:
60
- messages = [{"role": m.role, "content": m.content} for m in body.messages]
61
- provider = getattr(g4f.Provider, body.provider, None) if body.provider else None
62
-
63
- if body.stream:
64
- def generate():
65
- response = g4f.ChatCompletion.create(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  model=body.model,
67
  messages=messages,
68
  provider=provider,
69
  stream=True
70
  )
 
71
  for chunk in response:
72
- if chunk:
73
- payload = {
74
- "id": "chatcmpl-" + str(int(time.time())),
75
- "object": "chat.completion.chunk",
76
- "created": int(time.time()),
77
- "model": body.model,
78
- "choices": [{"delta": {"content": chunk}, "index": 0, "finish_reason": None}]
79
- }
80
- yield f"data: {json.dumps(payload)}\n\n"
 
 
 
 
 
 
 
 
 
 
81
  yield "data: [DONE]\n\n"
82
 
83
- return StreamingResponse(generate(), media_type="text/event-stream")
 
84
 
85
- # العادي
86
- response = await g4f.ChatCompletion.create_async(
87
- model=body.model,
88
- messages=messages,
89
- provider=provider
90
  )
91
-
92
- return {
93
- "id": "chatcmpl-g4f",
94
- "object": "chat.completion",
95
- "created": int(time.time()),
96
- "model": body.model,
97
- "choices": [{"index": 0, "message": {"role": "assistant", "content": response}, "finish_reason": "stop"}]
98
- }
99
 
100
- except Exception as e:
101
- logger.error(f"Error: {e}")
102
- raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os import json import time import logging import g4f from fastapi import FastAPI, HTTPException, Header from fastapi.responses import StreamingResponse from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from typing import List, Optional
2
+
3
+ ---------------- Logging ----------------
4
+
5
+ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(name)
6
+
7
+ ---------------- App ----------------
8
+
9
+ app = FastAPI( title="G4F OpenAI Compatible API", version="1.0" )
10
+
11
+ app.add_middleware( CORSMiddleware, allow_origins=[""], allow_credentials=False, allow_methods=[""], allow_headers=["*"] )
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  API_KEY = os.getenv("API_KEY", "your_fallback_secret")
14
 
15
+ ---------------- Models ----------------
16
+
17
+ class ChatMessage(BaseModel): role: str content: str
18
 
19
+ class ChatRequest(BaseModel): model: str = "gpt-4o-mini" messages: List[ChatMessage] stream: bool = False provider: Optional[str] = None max_tokens: Optional[int] = 2048 temperature: Optional[float] = 0.7
20
+
21
+ ---------------- Auth ----------------
 
 
22
 
23
  def verify_key(auth: str):
24
+
25
+ if not auth:
26
+ raise HTTPException(
27
+ status_code=401,
28
+ detail="Missing Authorization"
29
+ )
30
+
31
+ parts = auth.split()
32
+
33
+ if len(parts) != 2 or parts[0] != "Bearer":
34
+ raise HTTPException(
35
+ status_code=401,
36
+ detail="Malformed Authorization"
37
+ )
38
+
39
+ if parts[1] != API_KEY:
40
+ raise HTTPException(
41
+ status_code=401,
42
+ detail="Invalid API Key"
43
+ )
44
+
45
+ ---------------- Health ----------------
46
+
47
+ @app.get("/") async def health(): return { "status": "online" }
48
+
49
+ ---------------- Dynamic Models ----------------
50
+
51
+ @app.get("/v1/models") async def models( authorization: str = Header(None) ):
52
+
53
+ verify_key(authorization)
54
+
55
+ try:
56
+
57
+ model_data=[]
58
+
59
+ # الطريقة الأكثر استقرارًا مع g4f
60
+ if hasattr(g4f,"ModelUtils"):
61
+
62
+ for model_name in g4f.ModelUtils.convert.keys():
63
+
64
+ model_data.append({
65
+ "id":str(model_name),
66
+ "object":"model"
67
+ })
68
+
69
+ # fallback
70
+ if not model_data:
71
+
72
+ for name in dir(g4f.models):
73
+
74
+ if name.startswith("_"):
75
+ continue
76
+
77
+ value=getattr(
78
+ g4f.models,
79
+ name,
80
+ None
81
+ )
82
+
83
+ if isinstance(value,str):
84
+
85
+ model_data.append({
86
+ "id":value,
87
+ "object":"model"
88
+ })
89
+
90
+ unique={}
91
+
92
+ for m in model_data:
93
+ unique[m["id"]]=m
94
+
95
  return {
96
+ "object":"list",
97
+ "data":sorted(
98
+ unique.values(),
99
+ key=lambda x:x["id"]
100
+ )
101
  }
102
 
103
+ except Exception as e:
104
+
105
+ logger.exception(e)
106
+
107
+ return {
108
+ "object":"list",
109
+ "data":[
110
+ {
111
+ "id":"gpt-4o-mini",
112
+ "object":"model"
113
+ }
114
+ ]
115
+ }
116
+
117
+ ---------------- Chat ----------------
118
+
119
+ @app.post("/v1/chat/completions") async def chat( body: ChatRequest, authorization: str = Header(None) ):
120
+
121
+ verify_key(authorization)
122
+
123
+ try:
124
+
125
+ provider=None
126
+
127
+ if body.provider:
128
+
129
+ provider=getattr(
130
+ g4f.Provider,
131
+ body.provider,
132
+ None
133
+ )
134
+
135
+ if provider is None:
136
+ raise HTTPException(
137
+ status_code=400,
138
+ detail="Invalid provider"
139
+ )
140
+
141
+ messages=[
142
+ {
143
+ "role":m.role,
144
+ "content":m.content
145
+ }
146
+ for m in body.messages
147
+ ]
148
+
149
+ # -------- Streaming --------
150
+ if body.stream:
151
+
152
+ def generate():
153
+
154
+ try:
155
+
156
+ response=g4f.ChatCompletion.create(
157
  model=body.model,
158
  messages=messages,
159
  provider=provider,
160
  stream=True
161
  )
162
+
163
  for chunk in response:
164
+
165
+ payload={
166
+ "id":f"chatcmpl-{int(time.time())}",
167
+ "object":"chat.completion.chunk",
168
+ "created":int(time.time()),
169
+ "model":body.model,
170
+ "choices":[
171
+ {
172
+ "delta":{
173
+ "content":str(chunk)
174
+ },
175
+ "index":0,
176
+ "finish_reason":None
177
+ }
178
+ ]
179
+ }
180
+
181
+ yield f"data: {json.dumps(payload)}\n\n"
182
+
183
  yield "data: [DONE]\n\n"
184
 
185
+ except Exception as e:
186
+ logger.exception(e)
187
 
188
+ return StreamingResponse(
189
+ generate(),
190
+ media_type="text/event-stream"
 
 
191
  )
 
 
 
 
 
 
 
 
192
 
193
+ # -------- Non-stream --------
194
+ response=await g4f.ChatCompletion.create_async(
195
+ model=body.model,
196
+ messages=messages,
197
+ provider=provider
198
+ )
199
+
200
+ return {
201
+ "id":f"chatcmpl-{int(time.time())}",
202
+ "object":"chat.completion",
203
+ "created":int(time.time()),
204
+ "model":body.model,
205
+ "choices":[
206
+ {
207
+ "index":0,
208
+ "message":{
209
+ "role":"assistant",
210
+ "content":str(response)
211
+ },
212
+ "finish_reason":"stop"
213
+ }
214
+ ]
215
+ }
216
+
217
+ except Exception as e:
218
+
219
+ logger.exception(e)
220
+
221
+ raise HTTPException(
222
+ status_code=503,
223
+ detail=f"Provider error: {str(e)}"
224
+ )