bahi-bh commited on
Commit
3330050
·
verified ·
1 Parent(s): ef2ee4c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -44
app.py CHANGED
@@ -2,64 +2,58 @@ import os
2
  import time
3
  import random
4
  import traceback
 
5
 
6
- from fastapi import FastAPI, Depends, HTTPException, Security
7
- from fastapi.security.api_key import APIKeyHeader
8
  from pydantic import BaseModel
9
  import uvicorn
10
 
11
  from g4f.client import Client
12
  from g4f.Provider import __providers__
13
 
14
- MODEL = "gpt-4o-mini"
15
-
16
- MAX_RETRIES = 10
17
- TIMEOUT = 60
18
-
19
- # --- إعدادات مفاتيح الأمان من البيئة المستضافة ---
20
- # قراءة مفتاح حمايتك الخاص لـ FastAPI (إذا لم تجده سيضع قيمة افتراضية لحين ضبطه في الـ Secrets)
21
- MY_API_KEY = os.getenv("MY_PROJECT_API_KEY", "my_fallback_secret_key_123")
22
- api_key_header = APIKeyHeader(name="Authorization", auto_error=False)
23
-
24
- # قراءة مفتاح سيرفر Context7 من الـ Secrets الخاصة بـ Hugging Face
25
- CONTEXT7_KEY = os.getenv("CONTEXT7_API_KEY", "")
26
-
27
- # بناء قالب تكوين الـ MCP الخاص بـ Context7 برمجياً
28
- MCP_CONFIG = {
29
- "mcpServers": {
30
- "context7": {
31
- "url": "https://mcp.context7.com/mcp",
32
- "headers": {
33
- "Authorization": f"Bearer {CONTEXT7_KEY}"
34
  }
35
  }
36
- }
37
- }
 
 
 
38
 
39
- async def get_api_key(api_key_header: str = Security(api_key_header)):
40
- """دالة التحقق من أن العميل الخارجي يرسل مفتاح الـ API الصحيح"""
41
- if not api_key_header:
42
- raise HTTPException(status_code=403, detail="Missing API Key in Authorization header")
43
-
44
- # دعم صيغتي النقل العادية والمسبوقة بـ Bearer
45
- token = api_key_header.replace("Bearer ", "").strip()
46
- if token != MY_API_KEY:
47
- raise HTTPException(status_code=403, detail="Invalid API Key. Access Denied.")
48
- return token
49
 
 
 
 
 
50
 
51
  SAFE_PROVIDERS = []
52
 
53
  for provider in __providers__:
54
  try:
55
  name = provider.__name__.lower()
56
-
57
  if not getattr(provider, "working", False):
58
  continue
59
-
60
  if getattr(provider, "needs_auth", False):
61
  continue
62
-
63
  if getattr(provider, "use_nodriver", False):
64
  continue
65
 
@@ -117,6 +111,7 @@ class SmartG4F:
117
 
118
  for attempt in range(MAX_RETRIES):
119
  pool = self.provider_pool()
 
120
  if not pool:
121
  return {
122
  "success": False,
@@ -124,10 +119,10 @@ class SmartG4F:
124
  }
125
 
126
  provider = random.choice(pool)
 
127
  print(f"[TRY {attempt+1}] {provider.__name__}")
128
 
129
  try:
130
- # دمج إعداد الـ MCP لـ Context7 عبر الـ extra_body لضمان استدعائه مع الموديل المختار
131
  response = client.chat.completions.create(
132
  model=MODEL,
133
  provider=provider,
@@ -138,9 +133,6 @@ class SmartG4F:
138
  }
139
  ],
140
  timeout=TIMEOUT,
141
- extra_body={
142
- "mcp_config": MCP_CONFIG
143
- } if CONTEXT7_KEY else {} # يتم تفعيله فقط في حال وجود المفتاح لحمايتك من الأخطاء
144
  )
145
 
146
  text = response.choices[0].message.content
@@ -159,6 +151,7 @@ class SmartG4F:
159
 
160
  except Exception as e:
161
  err = str(e).lower()
 
162
  traceback.print_exc()
163
 
164
  errors.append({
@@ -169,13 +162,17 @@ class SmartG4F:
169
  if "429" in err:
170
  self.mark_bad(provider, 600)
171
  time.sleep(random.randint(10, 20))
 
172
  elif "cloudflare" in err:
173
  self.mark_bad(provider, 1200)
174
  time.sleep(20)
 
175
  elif "timeout" in err:
176
  self.mark_bad(provider, 300)
 
177
  else:
178
  self.mark_bad(provider, 180)
 
179
  continue
180
 
181
  return {
@@ -185,6 +182,7 @@ class SmartG4F:
185
 
186
 
187
  app = FastAPI()
 
188
  ai = SmartG4F()
189
 
190
 
@@ -192,6 +190,39 @@ class Query(BaseModel):
192
  prompt: str
193
 
194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  @app.get("/")
196
  async def home():
197
  return {
@@ -200,9 +231,8 @@ async def home():
200
  }
201
 
202
 
203
- # تفعيل الحماية بـ Depends(get_api_key) لمنع أي استهلاك خارجي غير مصرح به
204
- @app.post("/ask")
205
- async def ask(query: Query, token: str = Depends(get_api_key)):
206
  return ai.ask(query.prompt)
207
 
208
 
 
2
  import time
3
  import random
4
  import traceback
5
+ import json
6
 
7
+ from fastapi import FastAPI, HTTPException, Depends, Header
 
8
  from pydantic import BaseModel
9
  import uvicorn
10
 
11
  from g4f.client import Client
12
  from g4f.Provider import __providers__
13
 
14
+ # ============================================================
15
+ # إنشاء ملف config.json تلقائياً إذا لم يكن موجوداً
16
+ # (تقرأه مكتبة g4f تلقائياً عند إنشاء Client)
17
+ # ============================================================
18
+ CONFIG_PATH = "config.json"
19
+
20
+ if not os.path.exists(CONFIG_PATH):
21
+ context7_key = os.environ.get("CONTEXT7_API_KEY", "")
22
+ if context7_key:
23
+ config_data = {
24
+ "mcpServers": {
25
+ "context7": {
26
+ "url": "https://mcp.context7.com/mcp",
27
+ "headers": {
28
+ "Authorization": f"Bearer {context7_key}"
29
+ }
30
+ }
 
 
 
31
  }
32
  }
33
+ with open(CONFIG_PATH, "w", encoding="utf-8") as f:
34
+ json.dump(config_data, f, indent=2, ensure_ascii=False)
35
+ print("[+] config.json auto-generated for Context7 MCP")
36
+ else:
37
+ print("[!] CONTEXT7_API_KEY not set; skipping config.json creation")
38
 
39
+ # ============================================================
40
+ # المنطق الأصلي لم يُمسَّ
41
+ # ============================================================
 
 
 
 
 
 
 
42
 
43
+ MODEL = "gpt-4o-mini"
44
+
45
+ MAX_RETRIES = 10
46
+ TIMEOUT = 60
47
 
48
  SAFE_PROVIDERS = []
49
 
50
  for provider in __providers__:
51
  try:
52
  name = provider.__name__.lower()
 
53
  if not getattr(provider, "working", False):
54
  continue
 
55
  if getattr(provider, "needs_auth", False):
56
  continue
 
57
  if getattr(provider, "use_nodriver", False):
58
  continue
59
 
 
111
 
112
  for attempt in range(MAX_RETRIES):
113
  pool = self.provider_pool()
114
+
115
  if not pool:
116
  return {
117
  "success": False,
 
119
  }
120
 
121
  provider = random.choice(pool)
122
+
123
  print(f"[TRY {attempt+1}] {provider.__name__}")
124
 
125
  try:
 
126
  response = client.chat.completions.create(
127
  model=MODEL,
128
  provider=provider,
 
133
  }
134
  ],
135
  timeout=TIMEOUT,
 
 
 
136
  )
137
 
138
  text = response.choices[0].message.content
 
151
 
152
  except Exception as e:
153
  err = str(e).lower()
154
+
155
  traceback.print_exc()
156
 
157
  errors.append({
 
162
  if "429" in err:
163
  self.mark_bad(provider, 600)
164
  time.sleep(random.randint(10, 20))
165
+
166
  elif "cloudflare" in err:
167
  self.mark_bad(provider, 1200)
168
  time.sleep(20)
169
+
170
  elif "timeout" in err:
171
  self.mark_bad(provider, 300)
172
+
173
  else:
174
  self.mark_bad(provider, 180)
175
+
176
  continue
177
 
178
  return {
 
182
 
183
 
184
  app = FastAPI()
185
+
186
  ai = SmartG4F()
187
 
188
 
 
190
  prompt: str
191
 
192
 
193
+ # ============================================================
194
+ # نظام الحماية — Bearer Token
195
+ # ============================================================
196
+ def verify_api_key(authorization: str = Header(None)):
197
+ expected_key = os.environ.get("MY_PROJECT_API_KEY")
198
+ if not expected_key:
199
+ raise HTTPException(
200
+ status_code=500,
201
+ detail="Server misconfiguration: MY_PROJECT_API_KEY not set"
202
+ )
203
+
204
+ if not authorization:
205
+ raise HTTPException(
206
+ status_code=403,
207
+ detail="Missing Authorization header"
208
+ )
209
+
210
+ if not authorization.startswith("Bearer "):
211
+ raise HTTPException(
212
+ status_code=403,
213
+ detail="Invalid authorization header format. Expected: Bearer <token>"
214
+ )
215
+
216
+ token = authorization.split(" ", 1)[1] if " " in authorization else ""
217
+ if token != expected_key:
218
+ raise HTTPException(
219
+ status_code=403,
220
+ detail="Invalid API key"
221
+ )
222
+
223
+ return True
224
+
225
+
226
  @app.get("/")
227
  async def home():
228
  return {
 
231
  }
232
 
233
 
234
+ @app.post("/ask", dependencies=[Depends(verify_api_key)])
235
+ async def ask(query: Query):
 
236
  return ai.ask(query.prompt)
237
 
238