Rfym21 commited on
Commit
7be0b4f
·
verified ·
1 Parent(s): 9d856e1

Upload 25 files

Browse files
Dockerfile CHANGED
@@ -1,23 +1,23 @@
1
- # 选择精简版的Python镜像
2
- FROM python:3.11-slim
3
-
4
- # 设置工作目录
5
- WORKDIR /app
6
-
7
- # 复制应用代码到工作目录
8
- COPY . /app
9
-
10
- # 设置环境变量
11
- ENV DEMO_SECRET=123
12
-
13
- # 安装项目依赖
14
- RUN pip install --no-cache-dir -r requirements.txt
15
-
16
- # 创建应用程序所需的目录,并赋予必要权限
17
- RUN mkdir -p /app/data && chmod -R 777 /app/data
18
-
19
- # 暴露应用所使用的端口
20
- EXPOSE 5005
21
-
22
- # 启动应用
23
  CMD ["python", "app.py"]
 
1
+ # 选择精简版的Python镜像
2
+ FROM python:3.11-slim
3
+
4
+ # 设置工作目录
5
+ WORKDIR /app
6
+
7
+ # 复制应用代码到工作目录
8
+ COPY . /app
9
+
10
+ # 设置环境变量
11
+ ENV DEMO_SECRET=123
12
+
13
+ # 安装项目依赖
14
+ RUN pip install --no-cache-dir -r requirements.txt
15
+
16
+ # 创建应用程序所需的目录,并赋予必要权限
17
+ RUN mkdir -p /app/data && chmod -R 777 /app/data
18
+
19
+ # 暴露应用所使用的端口
20
+ EXPOSE 5005
21
+
22
+ # 启动应用
23
  CMD ["python", "app.py"]
chat2api.py CHANGED
@@ -1,4 +1,5 @@
1
  import asyncio
 
2
  import types
3
  import warnings
4
 
@@ -10,13 +11,14 @@ from fastapi.responses import StreamingResponse, JSONResponse
10
  from fastapi.security import OAuth2PasswordBearer
11
  from fastapi.templating import Jinja2Templates
12
  from starlette.background import BackgroundTask
 
13
 
14
  from chatgpt.ChatService import ChatService
15
- from chatgpt.authorization import refresh_all_tokens
16
  import chatgpt.globals as globals
17
  from chatgpt.reverseProxy import chatgpt_reverse_proxy
18
  from utils.Logger import logger
19
- from utils.config import api_prefix, scheduled_refresh
20
  from utils.retry import async_retry
21
 
22
  warnings.filterwarnings("ignore")
@@ -38,7 +40,8 @@ app.add_middleware(
38
  @app.on_event("startup")
39
  async def app_start():
40
  if scheduled_refresh:
41
- scheduler.add_job(id='refresh', func=refresh_all_tokens, trigger='cron', hour=3, minute=0, day='*/4', kwargs={'force_refresh': True})
 
42
  scheduler.start()
43
  asyncio.get_event_loop().call_later(0, lambda: asyncio.create_task(refresh_all_tokens(force_refresh=False)))
44
 
@@ -128,6 +131,103 @@ async def error_tokens():
128
  return {"status": "success", "error_tokens": error_tokens_list}
129
 
130
 
131
- @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"])
132
- async def reverse_proxy(request: Request, path: str):
133
- return await chatgpt_reverse_proxy(request, path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import asyncio
2
+ import time
3
  import types
4
  import warnings
5
 
 
11
  from fastapi.security import OAuth2PasswordBearer
12
  from fastapi.templating import Jinja2Templates
13
  from starlette.background import BackgroundTask
14
+ from starlette.responses import RedirectResponse, Response
15
 
16
  from chatgpt.ChatService import ChatService
17
+ from chatgpt.authorization import refresh_all_tokens, verify_token, get_req_token
18
  import chatgpt.globals as globals
19
  from chatgpt.reverseProxy import chatgpt_reverse_proxy
20
  from utils.Logger import logger
21
+ from utils.config import api_prefix, scheduled_refresh, enable_gateway
22
  from utils.retry import async_retry
23
 
24
  warnings.filterwarnings("ignore")
 
40
  @app.on_event("startup")
41
  async def app_start():
42
  if scheduled_refresh:
43
+ scheduler.add_job(id='refresh', func=refresh_all_tokens, trigger='cron', hour=3, minute=0, day='*/4',
44
+ kwargs={'force_refresh': True})
45
  scheduler.start()
46
  asyncio.get_event_loop().call_later(0, lambda: asyncio.create_task(refresh_all_tokens(force_refresh=False)))
47
 
 
131
  return {"status": "success", "error_tokens": error_tokens_list}
132
 
133
 
134
+ if enable_gateway:
135
+ @app.get("/", response_class=HTMLResponse)
136
+ async def chatgpt(request: Request):
137
+ seed_token = request.query_params.get("seed")
138
+ if not seed_token:
139
+ seed_token = request.cookies.get("seed_token")
140
+ if not seed_token:
141
+ seed_token = str(int(time.time()))
142
+ req_token = get_req_token(seed_token)
143
+ seed_token = await verify_token(req_token)
144
+
145
+ response = templates.TemplateResponse("chatgpt.html", {"request": request, "access_token": seed_token})
146
+ response.set_cookie("seed_token", value=seed_token)
147
+ return response
148
+
149
+
150
+ @app.get("/backend-api/gizmos/bootstrap")
151
+ async def get_gizmos_bootstrap():
152
+ return {"gizmos": []}
153
+
154
+
155
+ # @app.get("/backend-api/conversations")
156
+ # async def get_conversations():
157
+ # return {"items": [], "total": 0, "limit": 28, "offset": 0, "has_missing_conversations": False}
158
+
159
+ # @app.patch("/backend-api/conversations")
160
+ # async def get_conversations():
161
+ # return {"success": True, "message": None}
162
+
163
+
164
+ @app.get("/backend-api/me")
165
+ async def get_me():
166
+ created = int(time.time())
167
+ return {
168
+ "object": "user",
169
+ "id": "org-chatgpt",
170
+ "email": "chatgpt@openai.com",
171
+ "name": "ChatGPT",
172
+ "picture": "https://cdn.auth0.com/avatars/ai.png",
173
+ "created": created,
174
+ "phone_number": None,
175
+ "mfa_flag_enabled": False,
176
+ "amr": [],
177
+ "groups": [],
178
+ "orgs": {
179
+ "object": "list",
180
+ "data": [
181
+ {
182
+ "object": "organization",
183
+ "id": "org-chatgpt",
184
+ "created": 1715641300,
185
+ "title": "Personal",
186
+ "name": "user-chatgpt",
187
+ "description": "Personal org for chatgpt@openai.com",
188
+ "personal": True,
189
+ "settings": {},
190
+ "parent_org_id": None,
191
+ "is_default": False,
192
+ "role": "owner",
193
+ "is_scale_tier_authorized_purchaser": None,
194
+ "is_scim_managed": False,
195
+ "projects": {
196
+ "object": "list",
197
+ "data": []
198
+ },
199
+ "groups": [],
200
+ "geography": None
201
+ }
202
+ ]
203
+ },
204
+ "has_payg_project_spend_limit": None
205
+ }
206
+
207
+
208
+ banned_paths = ["backend-api/accounts/logout_all", "backend-api/accounts/deactivate",
209
+ "backend-api/user_system_messages"]
210
+ redirect_paths = ["auth/logout"]
211
+ chatgpt_paths = ["c/"]
212
+
213
+
214
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"])
215
+ async def reverse_proxy(request: Request, path: str):
216
+ for chatgpt_path in chatgpt_paths:
217
+ if chatgpt_path in path:
218
+ return await chatgpt(request)
219
+
220
+ for banned_path in banned_paths:
221
+ if banned_path in path:
222
+ return Response(status_code=404)
223
+
224
+ for redirect_path in redirect_paths:
225
+ if redirect_path in path:
226
+ redirect_url = str(request.base_url)
227
+ return RedirectResponse(url=f"{redirect_url}?seed={int(time.time())}", status_code=302)
228
+
229
+ return await chatgpt_reverse_proxy(request, path)
230
+ else:
231
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"])
232
+ async def reverse_proxy():
233
+ raise HTTPException(status_code=404, detail="Gateway is disabled")
chatgpt/ChatService.py CHANGED
@@ -8,27 +8,46 @@ from starlette.concurrency import run_in_threadpool
8
 
9
  from api.files import get_image_size, get_file_extension, determine_file_use_case
10
  from api.models import model_proxy
11
- from chatgpt.authorization import get_req_token, verify_token
12
  from chatgpt.chatFormat import api_messages_to_chat, stream_response, format_not_stream_response, head_process_response
13
  from chatgpt.chatLimit import check_is_limit, handle_request_limit
14
  from chatgpt.proofofWork import get_config, get_dpl, get_answer_token, get_requirements_token
15
 
16
  from utils.Client import Client
17
  from utils.Logger import logger
18
- from utils.config import proxy_url_list, chatgpt_base_url_list, ark0se_token_url_list, history_disabled, pow_difficulty, \
19
- conversation_only, enable_limit, upload_by_url, check_model, auth_key, user_agents_list, turnstile_solver_url
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
 
22
  class ChatService:
23
  def __init__(self, origin_token=None):
24
- self.user_agent = random.choice(user_agents_list) if user_agents_list else "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
25
  self.req_token = get_req_token(origin_token)
 
 
 
 
 
26
  self.chat_token = "gAAAAAB"
27
  self.s = None
28
  self.ws = None
29
 
30
  async def set_dynamic_data(self, data):
31
  if self.req_token:
 
 
32
  logger.info(f"Request token: {self.req_token}")
33
  req_len = len(self.req_token.split(","))
34
  if req_len == 1:
@@ -64,7 +83,7 @@ class ChatService:
64
  self.host_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
65
  self.ark0se_token_url = random.choice(ark0se_token_url_list) if ark0se_token_url_list else None
66
 
67
- self.s = Client(proxy=self.proxy_url)
68
 
69
  self.oai_device_id = str(uuid.uuid4())
70
  self.persona = None
@@ -85,13 +104,13 @@ class ChatService:
85
  'Origin': self.host_url,
86
  'Priority': 'u=1, i',
87
  'Referer': f'{self.host_url}/',
88
- 'Sec-Ch-Ua': '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"',
89
- 'Sec-Ch-Ua-Mobile': '?0',
90
- 'Sec-Ch-Ua-Platform': '"Windows"',
91
  'Sec-Fetch-Dest': 'empty',
92
  'Sec-Fetch-Mode': 'cors',
93
  'Sec-Fetch-Site': 'same-origin',
94
- 'User-Agent': self.user_agent
95
  }
96
  if self.access_token:
97
  self.base_url = self.host_url + "/backend-api"
@@ -155,12 +174,15 @@ class ChatService:
155
  models = r.json().get('models')
156
  if not any(self.req_model in model.get("slug", "") for model in models):
157
  logger.error(f"Model {self.req_model} not support.")
158
- raise HTTPException(status_code=404, detail={
159
- "message": f"The model `{self.origin_model}` does not exist or you do not have access to it.",
160
- "type": "invalid_request_error",
161
- "param": None,
162
- "code": "model_not_found"
163
- })
 
 
 
164
  else:
165
  raise HTTPException(status_code=404, detail="Failed to get models")
166
  else:
@@ -168,12 +190,15 @@ class ChatService:
168
  if self.persona != "chatgpt-paid":
169
  if self.req_model == "gpt-4":
170
  logger.error(f"Model {self.resp_model} not support for {self.persona}")
171
- raise HTTPException(status_code=404, detail={
172
- "message": f"The model `{self.origin_model}` does not exist or you do not have access to it.",
173
- "type": "invalid_request_error",
174
- "param": None,
175
- "code": "model_not_found"
176
- })
 
 
 
177
 
178
  turnstile = resp.get('turnstile', {})
179
  turnstile_required = turnstile.get('required')
@@ -181,7 +206,9 @@ class ChatService:
181
  turnstile_dx = turnstile.get("dx")
182
  try:
183
  if turnstile_solver_url:
184
- res = await self.s.post(turnstile_solver_url, json={"url": "https://chatgpt.com", "p": p, "dx": turnstile_dx})
 
 
185
  self.turnstile_token = res.json().get("t")
186
  except Exception as e:
187
  logger.info(f"Turnstile ignored: {e}")
@@ -197,12 +224,10 @@ class ChatService:
197
  if not self.ark0se_token_url:
198
  raise HTTPException(status_code=403, detail="Ark0se service required")
199
  ark0se_dx = ark0se.get("dx")
200
- ark0se_client = Client()
201
  try:
202
  r2 = await ark0se_client.post(
203
- url=self.ark0se_token_url,
204
- json={"blob": ark0se_dx, "method": ark0se_method},
205
- timeout=15
206
  )
207
  r2esp = r2.json()
208
  logger.info(f"ark0se_token: {r2esp}")
@@ -220,11 +245,11 @@ class ChatService:
220
  if proofofwork_required:
221
  proofofwork_diff = proofofwork.get("difficulty")
222
  if proofofwork_diff <= pow_difficulty:
223
- raise HTTPException(status_code=403,
224
- detail=f"Proof of work difficulty too high: {proofofwork_diff}")
225
  proofofwork_seed = proofofwork.get("seed")
226
- self.proof_token, solved = await run_in_threadpool(get_answer_token, proofofwork_seed,
227
- proofofwork_diff, config)
 
228
  if not solved:
229
  raise HTTPException(status_code=403, detail="Failed to solve proof of work")
230
 
@@ -254,11 +279,13 @@ class ChatService:
254
  logger.error(f"Failed to format messages: {str(e)}")
255
  raise HTTPException(status_code=400, detail="Failed to format messages.")
256
  self.chat_headers = self.base_headers.copy()
257
- self.chat_headers.update({
258
- 'Accept': 'text/event-stream',
259
- 'Openai-Sentinel-Chat-Requirements-Token': self.chat_token,
260
- 'Openai-Sentinel-Proof-Token': self.proof_token,
261
- })
 
 
262
  if self.ark0se_token:
263
  self.chat_headers['Openai-Sentinel-Ark' + 'ose-Token'] = self.ark0se_token
264
 
@@ -294,7 +321,7 @@ class ChatService:
294
  "suggestions": [],
295
  "timezone_offset_min": -480,
296
  "variant_purpose": "comparison_implicit",
297
- "websocket_request_id": f"{uuid.uuid4()}"
298
  }
299
  if self.conversation_id:
300
  self.chat_request['conversation_id'] = self.conversation_id
@@ -304,8 +331,7 @@ class ChatService:
304
  try:
305
  url = f'{self.base_url}/conversation'
306
  stream = self.data.get("stream", False)
307
- r = await self.s.post_stream(url, headers=self.chat_headers, json=self.chat_request, timeout=10,
308
- stream=True)
309
  if r.status_code != 200:
310
  rtext = await r.atext()
311
  if "application/json" == r.headers.get("Content-Type", ""):
@@ -327,13 +353,19 @@ class ChatService:
327
  if "text/event-stream" in content_type:
328
  res, start = await head_process_response(r.aiter_lines())
329
  if not start:
330
- raise HTTPException(status_code=403, detail="Our systems have detected unusual activity coming from your system. Please try again later.")
 
 
 
331
  if stream:
332
  return stream_response(self, res, self.resp_model, self.max_tokens)
333
  else:
334
  return await format_not_stream_response(
335
- stream_response(self, res, self.resp_model, self.max_tokens), self.prompt_tokens,
336
- self.max_tokens, self.resp_model)
 
 
 
337
  elif "application/json" in content_type:
338
  rtext = await r.atext()
339
  resp = json.loads(rtext)
@@ -376,12 +408,12 @@ class ChatService:
376
  url = f'{self.base_url}/files'
377
  headers = self.base_headers.copy()
378
  try:
379
- r = await self.s.post(url, headers=headers, json={
380
- "file_name": file_name,
381
- "file_size": file_size,
382
- "timezone_offset_min": -480,
383
- "use_case": use_case
384
- }, timeout=5)
385
  if r.status_code == 200:
386
  res = r.json()
387
  file_id = res.get('file_id')
@@ -395,12 +427,14 @@ class ChatService:
395
 
396
  async def upload(self, upload_url, file_content, mime_type):
397
  headers = self.base_headers.copy()
398
- headers.update({
399
- 'Accept': 'application/json, text/plain, */*',
400
- 'Content-Type': mime_type,
401
- 'X-Ms-Blob-Type': 'BlockBlob',
402
- 'X-Ms-Version': '2020-04-08'
403
- })
 
 
404
  headers.pop('Authorization', None)
405
  try:
406
  r = await self.s.put(upload_url, headers=headers, data=file_content)
@@ -438,7 +472,7 @@ class ChatService:
438
  "mime_type": mime_type,
439
  "width": width,
440
  "height": height,
441
- "use_case": use_case
442
  }
443
  logger.info(f"File_meta: {file_meta}")
444
  return file_meta
@@ -468,10 +502,7 @@ class ChatService:
468
  async def get_response_file_url(self, conversation_id, message_id, sandbox_path):
469
  try:
470
  url = f"{self.base_url}/conversation/{conversation_id}/interpreter/download"
471
- params = {
472
- "message_id": message_id,
473
- "sandbox_path": sandbox_path
474
- }
475
  headers = self.base_headers.copy()
476
  r = await self.s.get(url, headers=headers, params=params, timeout=10)
477
  if r.status_code == 200:
 
8
 
9
  from api.files import get_image_size, get_file_extension, determine_file_use_case
10
  from api.models import model_proxy
11
+ from chatgpt.authorization import get_req_token, verify_token, get_ua
12
  from chatgpt.chatFormat import api_messages_to_chat, stream_response, format_not_stream_response, head_process_response
13
  from chatgpt.chatLimit import check_is_limit, handle_request_limit
14
  from chatgpt.proofofWork import get_config, get_dpl, get_answer_token, get_requirements_token
15
 
16
  from utils.Client import Client
17
  from utils.Logger import logger
18
+ from utils.config import (
19
+ proxy_url_list,
20
+ chatgpt_base_url_list,
21
+ ark0se_token_url_list,
22
+ history_disabled,
23
+ pow_difficulty,
24
+ conversation_only,
25
+ enable_limit,
26
+ upload_by_url,
27
+ check_model,
28
+ auth_key,
29
+ user_agents_list,
30
+ turnstile_solver_url,
31
+ )
32
 
33
 
34
  class ChatService:
35
  def __init__(self, origin_token=None):
36
+ # self.user_agent = random.choice(user_agents_list) if user_agents_list else "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
37
  self.req_token = get_req_token(origin_token)
38
+ self.ua = get_ua(self.req_token)
39
+ self.user_agent = self.ua.get(
40
+ "User-Agent",
41
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
42
+ )
43
  self.chat_token = "gAAAAAB"
44
  self.s = None
45
  self.ws = None
46
 
47
  async def set_dynamic_data(self, data):
48
  if self.req_token:
49
+ logger.info(f"Request impersonate: {self.ua.get('impersonate')}")
50
+ logger.info(f"Request ua:{self.user_agent}")
51
  logger.info(f"Request token: {self.req_token}")
52
  req_len = len(self.req_token.split(","))
53
  if req_len == 1:
 
83
  self.host_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
84
  self.ark0se_token_url = random.choice(ark0se_token_url_list) if ark0se_token_url_list else None
85
 
86
+ self.s = Client(proxy=self.proxy_url, impersonate=self.ua.get("impersonate", "safari15_3"))
87
 
88
  self.oai_device_id = str(uuid.uuid4())
89
  self.persona = None
 
104
  'Origin': self.host_url,
105
  'Priority': 'u=1, i',
106
  'Referer': f'{self.host_url}/',
107
+ 'Sec-Ch-Ua': self.ua.get("Sec-Ch-Ua", '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"'),
108
+ 'Sec-Ch-Ua-Mobile': self.ua.get("Sec-Ch-Ua-Mobile", "?0"),
109
+ 'Sec-Ch-Ua-Platform': self.ua.get("Sec-Ch-Ua-Platform", '"Windows"'),
110
  'Sec-Fetch-Dest': 'empty',
111
  'Sec-Fetch-Mode': 'cors',
112
  'Sec-Fetch-Site': 'same-origin',
113
+ 'User-Agent': self.user_agent,
114
  }
115
  if self.access_token:
116
  self.base_url = self.host_url + "/backend-api"
 
174
  models = r.json().get('models')
175
  if not any(self.req_model in model.get("slug", "") for model in models):
176
  logger.error(f"Model {self.req_model} not support.")
177
+ raise HTTPException(
178
+ status_code=404,
179
+ detail={
180
+ "message": f"The model `{self.origin_model}` does not exist or you do not have access to it.",
181
+ "type": "invalid_request_error",
182
+ "param": None,
183
+ "code": "model_not_found",
184
+ },
185
+ )
186
  else:
187
  raise HTTPException(status_code=404, detail="Failed to get models")
188
  else:
 
190
  if self.persona != "chatgpt-paid":
191
  if self.req_model == "gpt-4":
192
  logger.error(f"Model {self.resp_model} not support for {self.persona}")
193
+ raise HTTPException(
194
+ status_code=404,
195
+ detail={
196
+ "message": f"The model `{self.origin_model}` does not exist or you do not have access to it.",
197
+ "type": "invalid_request_error",
198
+ "param": None,
199
+ "code": "model_not_found",
200
+ },
201
+ )
202
 
203
  turnstile = resp.get('turnstile', {})
204
  turnstile_required = turnstile.get('required')
 
206
  turnstile_dx = turnstile.get("dx")
207
  try:
208
  if turnstile_solver_url:
209
+ res = await self.s.post(
210
+ turnstile_solver_url, json={"url": "https://chatgpt.com", "p": p, "dx": turnstile_dx}
211
+ )
212
  self.turnstile_token = res.json().get("t")
213
  except Exception as e:
214
  logger.info(f"Turnstile ignored: {e}")
 
224
  if not self.ark0se_token_url:
225
  raise HTTPException(status_code=403, detail="Ark0se service required")
226
  ark0se_dx = ark0se.get("dx")
227
+ ark0se_client = Client(impersonate=self.ua.get("impersonate", "safari15_3"))
228
  try:
229
  r2 = await ark0se_client.post(
230
+ url=self.ark0se_token_url, json={"blob": ark0se_dx, "method": ark0se_method}, timeout=15
 
 
231
  )
232
  r2esp = r2.json()
233
  logger.info(f"ark0se_token: {r2esp}")
 
245
  if proofofwork_required:
246
  proofofwork_diff = proofofwork.get("difficulty")
247
  if proofofwork_diff <= pow_difficulty:
248
+ raise HTTPException(status_code=403, detail=f"Proof of work difficulty too high: {proofofwork_diff}")
 
249
  proofofwork_seed = proofofwork.get("seed")
250
+ self.proof_token, solved = await run_in_threadpool(
251
+ get_answer_token, proofofwork_seed, proofofwork_diff, config
252
+ )
253
  if not solved:
254
  raise HTTPException(status_code=403, detail="Failed to solve proof of work")
255
 
 
279
  logger.error(f"Failed to format messages: {str(e)}")
280
  raise HTTPException(status_code=400, detail="Failed to format messages.")
281
  self.chat_headers = self.base_headers.copy()
282
+ self.chat_headers.update(
283
+ {
284
+ 'Accept': 'text/event-stream',
285
+ 'Openai-Sentinel-Chat-Requirements-Token': self.chat_token,
286
+ 'Openai-Sentinel-Proof-Token': self.proof_token,
287
+ }
288
+ )
289
  if self.ark0se_token:
290
  self.chat_headers['Openai-Sentinel-Ark' + 'ose-Token'] = self.ark0se_token
291
 
 
321
  "suggestions": [],
322
  "timezone_offset_min": -480,
323
  "variant_purpose": "comparison_implicit",
324
+ "websocket_request_id": f"{uuid.uuid4()}",
325
  }
326
  if self.conversation_id:
327
  self.chat_request['conversation_id'] = self.conversation_id
 
331
  try:
332
  url = f'{self.base_url}/conversation'
333
  stream = self.data.get("stream", False)
334
+ r = await self.s.post_stream(url, headers=self.chat_headers, json=self.chat_request, timeout=10, stream=True)
 
335
  if r.status_code != 200:
336
  rtext = await r.atext()
337
  if "application/json" == r.headers.get("Content-Type", ""):
 
353
  if "text/event-stream" in content_type:
354
  res, start = await head_process_response(r.aiter_lines())
355
  if not start:
356
+ raise HTTPException(
357
+ status_code=403,
358
+ detail="Our systems have detected unusual activity coming from your system. Please try again later.",
359
+ )
360
  if stream:
361
  return stream_response(self, res, self.resp_model, self.max_tokens)
362
  else:
363
  return await format_not_stream_response(
364
+ stream_response(self, res, self.resp_model, self.max_tokens),
365
+ self.prompt_tokens,
366
+ self.max_tokens,
367
+ self.resp_model,
368
+ )
369
  elif "application/json" in content_type:
370
  rtext = await r.atext()
371
  resp = json.loads(rtext)
 
408
  url = f'{self.base_url}/files'
409
  headers = self.base_headers.copy()
410
  try:
411
+ r = await self.s.post(
412
+ url,
413
+ headers=headers,
414
+ json={"file_name": file_name, "file_size": file_size, "timezone_offset_min": -480, "use_case": use_case},
415
+ timeout=5,
416
+ )
417
  if r.status_code == 200:
418
  res = r.json()
419
  file_id = res.get('file_id')
 
427
 
428
  async def upload(self, upload_url, file_content, mime_type):
429
  headers = self.base_headers.copy()
430
+ headers.update(
431
+ {
432
+ 'Accept': 'application/json, text/plain, */*',
433
+ 'Content-Type': mime_type,
434
+ 'X-Ms-Blob-Type': 'BlockBlob',
435
+ 'X-Ms-Version': '2020-04-08',
436
+ }
437
+ )
438
  headers.pop('Authorization', None)
439
  try:
440
  r = await self.s.put(upload_url, headers=headers, data=file_content)
 
472
  "mime_type": mime_type,
473
  "width": width,
474
  "height": height,
475
+ "use_case": use_case,
476
  }
477
  logger.info(f"File_meta: {file_meta}")
478
  return file_meta
 
502
  async def get_response_file_url(self, conversation_id, message_id, sandbox_path):
503
  try:
504
  url = f"{self.base_url}/conversation/{conversation_id}/interpreter/download"
505
+ params = {"message_id": message_id, "sandbox_path": sandbox_path}
 
 
 
506
  headers = self.base_headers.copy()
507
  r = await self.s.get(url, headers=headers, params=params, timeout=10)
508
  if r.status_code == 200:
chatgpt/authorization.py CHANGED
@@ -1,28 +1,59 @@
1
  import asyncio
 
 
2
 
 
3
  from fastapi import HTTPException
4
 
 
5
  from chatgpt.refreshToken import rt2ac
6
  from utils.Logger import logger
7
- from utils.config import authorization_list
8
- import chatgpt.globals as globals
 
 
 
9
 
 
 
 
 
 
 
 
 
10
 
11
- def get_req_token(req_token):
12
  if req_token in authorization_list:
13
- if len(globals.token_list) - len(globals.error_token_list) > 0:
14
- globals.count += 1
15
- globals.count %= len(globals.token_list)
16
- while globals.token_list[globals.count] in globals.error_token_list:
 
17
  globals.count += 1
18
- globals.count %= len(globals.token_list)
19
- return globals.token_list[globals.count]
20
  else:
21
  return None
22
  else:
23
  return req_token
24
 
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  async def verify_token(req_token):
27
  if not req_token:
28
  if authorization_list:
@@ -45,7 +76,7 @@ async def verify_token(req_token):
45
 
46
 
47
  async def refresh_all_tokens(force_refresh=False):
48
- for token in globals.token_list:
49
  if len(token) == 45:
50
  try:
51
  await asyncio.sleep(2)
 
1
  import asyncio
2
+ import os
3
+ import random
4
 
5
+ import ua_generator
6
  from fastapi import HTTPException
7
 
8
+ import chatgpt.globals as globals
9
  from chatgpt.refreshToken import rt2ac
10
  from utils.Logger import logger
11
+ from utils.config import authorization_list, random_token
12
+
13
+ os.environ['PYTHONHASHSEED'] = '0'
14
+ random.seed(0)
15
+
16
 
17
+ def get_req_token(req_token, seed=None):
18
+ available_token_list = list(set(globals.token_list) - set(globals.error_token_list))
19
+ length = len(available_token_list)
20
+ if seed and length > 0:
21
+ req_token = globals.token_list[hash(seed) % length]
22
+ while req_token in globals.error_token_list:
23
+ req_token = random.choice(globals.token_list)
24
+ return req_token
25
 
 
26
  if req_token in authorization_list:
27
+ if len(available_token_list) > 0:
28
+ if random_token:
29
+ req_token = random.choice(available_token_list)
30
+ return req_token
31
+ else:
32
  globals.count += 1
33
+ globals.count %= length
34
+ return available_token_list[globals.count]
35
  else:
36
  return None
37
  else:
38
  return req_token
39
 
40
 
41
+ def get_ua(req_token):
42
+ user_agent = globals.user_agent_map.get(req_token, "")
43
+ # token为空,免登录用户,则随机生成ua
44
+ if not user_agent:
45
+ ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
46
+ return {
47
+ "User-Agent": ua.text,
48
+ "Sec-Ch-Ua-Platform": ua.platform,
49
+ "Sec-Ch-Ua": ua.ch.brands,
50
+ "Sec-Ch-Ua-Mobile": ua.ch.mobile,
51
+ "impersonate": random.choice(globals.impersonate_list),
52
+ }
53
+ else:
54
+ return user_agent
55
+
56
+
57
  async def verify_token(req_token):
58
  if not req_token:
59
  if authorization_list:
 
76
 
77
 
78
  async def refresh_all_tokens(force_refresh=False):
79
+ for token in list(set(globals.token_list) - set(globals.error_token_list)):
80
  if len(token) == 45:
81
  try:
82
  await asyncio.sleep(2)
chatgpt/globals.py CHANGED
@@ -1,6 +1,9 @@
1
  import json
2
  import os
3
 
 
 
 
4
  from utils.Logger import logger
5
 
6
  DATA_FOLDER = "data"
@@ -8,13 +11,28 @@ TOKENS_FILE = os.path.join(DATA_FOLDER, "token.txt")
8
  REFRESH_MAP_FILE = os.path.join(DATA_FOLDER, "refresh_map.json")
9
  ERROR_TOKENS_FILE = os.path.join(DATA_FOLDER, "error_token.txt")
10
  WSS_MAP_FILE = os.path.join(DATA_FOLDER, "wss_map.json")
 
11
 
12
  count = 0
13
  token_list = []
14
  error_token_list = []
15
  refresh_map = {}
16
  wss_map = {}
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  if not os.path.exists(DATA_FOLDER):
20
  os.makedirs(DATA_FOLDER)
@@ -30,8 +48,8 @@ if os.path.exists(WSS_MAP_FILE):
30
  wss_map = json.load(file)
31
  else:
32
  wss_map = {}
33
-
34
-
35
  if os.path.exists(TOKENS_FILE):
36
  with open(TOKENS_FILE, "r", encoding="utf-8") as f:
37
  for line in f:
@@ -41,6 +59,7 @@ else:
41
  with open(TOKENS_FILE, "w", encoding="utf-8") as f:
42
  pass
43
 
 
44
  if os.path.exists(ERROR_TOKENS_FILE):
45
  with open(ERROR_TOKENS_FILE, "r", encoding="utf-8") as f:
46
  for line in f:
@@ -50,5 +69,37 @@ else:
50
  with open(ERROR_TOKENS_FILE, "w", encoding="utf-8") as f:
51
  pass
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  if token_list:
54
- logger.info(f"Token list count: {len(token_list)}, Error token list count: {len(error_token_list)}")
 
1
  import json
2
  import os
3
 
4
+ import ua_generator
5
+ import random
6
+
7
  from utils.Logger import logger
8
 
9
  DATA_FOLDER = "data"
 
11
  REFRESH_MAP_FILE = os.path.join(DATA_FOLDER, "refresh_map.json")
12
  ERROR_TOKENS_FILE = os.path.join(DATA_FOLDER, "error_token.txt")
13
  WSS_MAP_FILE = os.path.join(DATA_FOLDER, "wss_map.json")
14
+ USER_AGENTS_FILE = os.path.join(DATA_FOLDER, "user_agents.json")
15
 
16
  count = 0
17
  token_list = []
18
  error_token_list = []
19
  refresh_map = {}
20
  wss_map = {}
21
+ user_agent_map = {}
22
+ impersonate_list = [
23
+ "chrome99",
24
+ "chrome100",
25
+ "chrome101",
26
+ "chrome104",
27
+ "chrome107",
28
+ "chrome110",
29
+ "chrome116",
30
+ "chrome119",
31
+ "chrome120",
32
+ "chrome123",
33
+ "edge99",
34
+ "edge101",
35
+ ]
36
 
37
  if not os.path.exists(DATA_FOLDER):
38
  os.makedirs(DATA_FOLDER)
 
48
  wss_map = json.load(file)
49
  else:
50
  wss_map = {}
51
+
52
+
53
  if os.path.exists(TOKENS_FILE):
54
  with open(TOKENS_FILE, "r", encoding="utf-8") as f:
55
  for line in f:
 
59
  with open(TOKENS_FILE, "w", encoding="utf-8") as f:
60
  pass
61
 
62
+
63
  if os.path.exists(ERROR_TOKENS_FILE):
64
  with open(ERROR_TOKENS_FILE, "r", encoding="utf-8") as f:
65
  for line in f:
 
69
  with open(ERROR_TOKENS_FILE, "w", encoding="utf-8") as f:
70
  pass
71
 
72
+ if os.path.exists(USER_AGENTS_FILE):
73
+ with open(USER_AGENTS_FILE, "r", encoding="utf-8") as f:
74
+ user_agent_map = json.load(f)
75
+ # token数量变化时,更新ua
76
+ if len(user_agent_map.keys()) != len(token_list):
77
+ new_tokens = list(set(token_list) - user_agent_map.keys())
78
+ for token in new_tokens:
79
+ ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
80
+ ua_dict = {
81
+ "User-Agent": ua.text,
82
+ "Sec-Ch-Ua-Platform": ua.platform,
83
+ "Sec-Ch-Ua": ua.ch.brands,
84
+ "Sec-Ch-Ua-Mobile": ua.ch.mobile,
85
+ "impersonate": random.choice(impersonate_list),
86
+ }
87
+ user_agent_map[token] = ua_dict
88
+ with open(USER_AGENTS_FILE, "w", encoding="utf-8") as f:
89
+ f.write(json.dumps(user_agent_map, indent=4))
90
+ else:
91
+ for token in token_list:
92
+ ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge'), platform=('windows', 'macos'))
93
+ ua_dict = {
94
+ "User-Agent": ua.text,
95
+ "Sec-Ch-Ua-Platform": ua.platform,
96
+ "Sec-Ch-Ua": ua.ch.brands,
97
+ "Sec-Ch-Ua-Mobile": ua.ch.mobile,
98
+ "impersonate": random.choice(impersonate_list),
99
+ }
100
+ user_agent_map[token] = ua_dict
101
+ with open(USER_AGENTS_FILE, "w", encoding="utf-8") as f:
102
+ f.write(json.dumps(user_agent_map, indent=4))
103
+
104
  if token_list:
105
+ logger.info(f"Token list count: {len(token_list)}, Error token list count: {len(error_token_list)}")
chatgpt/refreshToken.py CHANGED
@@ -45,11 +45,14 @@ async def chat_refresh(refresh_token):
45
  access_token = r.json()['access_token']
46
  return access_token
47
  else:
48
- with open(globals.ERROR_TOKENS_FILE, "a", encoding="utf-8") as f:
49
- f.write(refresh_token + "\n")
50
- if refresh_token not in globals.error_token_list:
51
- globals.error_token_list.append(refresh_token)
52
- raise Exception(r.text[:100])
 
 
 
53
  except Exception as e:
54
  logger.error(f"Failed to refresh access_token `{refresh_token}`: {str(e)}")
55
  raise HTTPException(status_code=500, detail=f"Failed to refresh access_token.")
 
45
  access_token = r.json()['access_token']
46
  return access_token
47
  else:
48
+ if "invalid_grant" in r.text or "access_denied" in r.text:
49
+ if refresh_token not in globals.error_token_list:
50
+ globals.error_token_list.append(refresh_token)
51
+ with open(globals.ERROR_TOKENS_FILE, "a", encoding="utf-8") as f:
52
+ f.write(refresh_token + "\n")
53
+ raise Exception(r.text)
54
+ else:
55
+ raise Exception(r.text[:300])
56
  except Exception as e:
57
  logger.error(f"Failed to refresh access_token `{refresh_token}`: {str(e)}")
58
  raise HTTPException(status_code=500, detail=f"Failed to refresh access_token.")
chatgpt/reverseProxy.py CHANGED
@@ -1,9 +1,11 @@
 
1
  import random
2
 
3
  from fastapi import Request, HTTPException
4
  from fastapi.responses import StreamingResponse, Response
5
  from starlette.background import BackgroundTask
6
 
 
7
  from utils.Client import Client
8
  from utils.config import chatgpt_base_url_list, proxy_url_list, enable_gateway
9
 
@@ -60,105 +62,94 @@ headers_reject_list = [
60
 
61
 
62
  async def chatgpt_reverse_proxy(request: Request, path: str):
63
- if not enable_gateway:
64
- raise HTTPException(status_code=404, detail="Gateway is disabled")
65
  try:
66
  origin_host = request.url.netloc
67
- if ":" in origin_host:
68
- petrol = "http"
69
- else:
70
  petrol = "https"
71
- if path.startswith("v1/"):
72
- base_url = "https://ab.chatgpt.com"
73
  else:
74
- base_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
75
- if "/assets" in path:
76
- base_url = "https://cdn.oaistatic.com"
 
 
 
77
 
78
  params = dict(request.query_params)
 
 
79
  headers = {
80
  key: value for key, value in request.headers.items()
81
- if (key.lower() not in ["host", "origin", "referer", "user-agent",
82
- "authorization"] and key.lower() not in headers_reject_list)
83
  }
84
- request_cookies = dict(request.cookies)
85
 
 
 
 
 
 
 
 
 
 
86
  headers.update({
87
- "accept-Language": "en-US,en;q=0.9",
88
  "host": base_url.replace("https://", "").replace("http://", ""),
89
  "origin": base_url,
90
  "referer": f"{base_url}/",
91
- "sec-ch-ua": '"Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"',
92
- "sec-ch-ua-mobile": "?0",
93
- "sec-ch-ua-platform": "\"Windows\"",
94
  "sec-fetch-dest": "empty",
95
  "sec-fetch-mode": "cors",
96
  "sec-fetch-site": "same-origin",
97
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0"
98
  })
99
 
100
- if request.headers.get('Authorization'):
101
- headers['Authorization'] = request.headers['Authorization']
102
-
103
- if headers.get("Content-Type") == "application/json":
104
- data = await request.json()
 
 
 
 
 
105
  else:
106
- data = await request.body()
 
 
107
 
108
  client = Client(proxy=random.choice(proxy_url_list) if proxy_url_list else None)
109
  try:
110
  background = BackgroundTask(client.close)
111
  r = await client.request(request.method, f"{base_url}/{path}", params=params, headers=headers,
112
  cookies=request_cookies, data=data, stream=True, allow_redirects=False)
113
- if r.status_code == 304:
114
- return Response(status_code=304, background=background)
115
- elif r.status_code == 307:
116
- if "oai-dm=1" not in r.headers.get("Location"):
117
- return Response(status_code=307, headers={
118
- "Location": r.headers.get("Location").replace("chat.openai.com", origin_host)
119
- .replace("chatgpt.com", origin_host)
120
- .replace("https", petrol)}, background=background)
121
- else:
122
- return Response(status_code=307, headers={"Location": r.headers.get("Location")},
123
- background=background)
124
- elif r.status_code == 302:
125
  return Response(status_code=302,
126
  headers={"Location": r.headers.get("Location").replace("chatgpt.com", origin_host)
127
- .replace("chat.openai.com", origin_host)
128
- .replace("ab.chatgpt.com", origin_host)
129
  .replace("cdn.oaistatic.com", origin_host)
130
  .replace("https", petrol)}, background=background)
131
  elif 'stream' in r.headers.get("content-type", ""):
132
  return StreamingResponse(r.aiter_content(), media_type=r.headers.get("content-type", ""),
133
  background=background)
134
  else:
135
- if "/conversation" in path or "/register-websocket" in path:
136
  response = Response(content=(await r.atext()), media_type=r.headers.get("content-type"),
137
  status_code=r.status_code, background=background)
138
  else:
139
  content = ((await r.atext()).replace("chatgpt.com", origin_host)
140
- .replace("chat.openai.com", origin_host)
141
- .replace("ab.chatgpt.com", origin_host)
142
  .replace("cdn.oaistatic.com", origin_host)
 
143
  .replace("https", petrol))
144
  rheaders = dict(r.headers)
145
- cache_control = rheaders.get("cache-control", "")
146
  content_type = rheaders.get("content-type", "")
 
 
147
  rheaders = {
148
  "cache-control": cache_control,
149
- "content-type": content_type
 
150
  }
151
  response = Response(content=content, headers=rheaders,
152
  status_code=r.status_code, background=background)
153
- for cookie_name in r.cookies:
154
- if cookie_name in request_cookies:
155
- continue
156
- for cookie_domain in [".chatgpt.com"]:
157
- cookie_value = r.cookies.get(name=cookie_name, domain=cookie_domain)
158
- if cookie_name.startswith("__"):
159
- response.set_cookie(key=cookie_name, value=cookie_value, secure=True, httponly=True)
160
- else:
161
- response.set_cookie(key=cookie_name, value=cookie_value)
162
  return response
163
  except Exception:
164
  await client.close()
 
1
+ import json
2
  import random
3
 
4
  from fastapi import Request, HTTPException
5
  from fastapi.responses import StreamingResponse, Response
6
  from starlette.background import BackgroundTask
7
 
8
+ from chatgpt.authorization import verify_token, get_req_token
9
  from utils.Client import Client
10
  from utils.config import chatgpt_base_url_list, proxy_url_list, enable_gateway
11
 
 
62
 
63
 
64
  async def chatgpt_reverse_proxy(request: Request, path: str):
 
 
65
  try:
66
  origin_host = request.url.netloc
67
+ if request.url.is_secure:
 
 
68
  petrol = "https"
 
 
69
  else:
70
+ petrol = "http"
71
+ if "x-forwarded-proto" in request.headers:
72
+ petrol = request.headers["x-forwarded-proto"]
73
+ if "cf-visitor" in request.headers:
74
+ cf_visitor = json.loads(request.headers["cf-visitor"])
75
+ petrol = cf_visitor.get("scheme", petrol)
76
 
77
  params = dict(request.query_params)
78
+ request_cookies = dict(request.cookies)
79
+
80
  headers = {
81
  key: value for key, value in request.headers.items()
82
+ if (key.lower() not in ["host", "origin", "referer"] and key.lower() not in headers_reject_list)
 
83
  }
 
84
 
85
+ base_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
86
+ if "assets/" in path:
87
+ base_url = "https://cdn.oaistatic.com"
88
+ if "file-" in path and "backend-api" not in path:
89
+ base_url = "https://files.oaiusercontent.com"
90
+
91
+ # req_token = request.cookies.get("req_token")
92
+ # ua = get_ua(req_token)
93
+ # headers.update(ua)
94
  headers.update({
95
+ "accept-language": "en-US,en;q=0.9",
96
  "host": base_url.replace("https://", "").replace("http://", ""),
97
  "origin": base_url,
98
  "referer": f"{base_url}/",
 
 
 
99
  "sec-fetch-dest": "empty",
100
  "sec-fetch-mode": "cors",
101
  "sec-fetch-site": "same-origin",
 
102
  })
103
 
104
+ seed_token = headers.get("authorization", "").replace("Bearer ", "")
105
+ if seed_token:
106
+ req_token = get_req_token(seed_token)
107
+ access_token = await verify_token(req_token)
108
+ if access_token.startswith("eyJhbGciOi"):
109
+ headers.update({"authorization": access_token})
110
+ else:
111
+ req_token = get_req_token(None, seed_token)
112
+ access_token = await verify_token(req_token)
113
+ headers.update({"authorization": access_token})
114
  else:
115
+ headers.pop("authorization", None)
116
+
117
+ data = await request.body()
118
 
119
  client = Client(proxy=random.choice(proxy_url_list) if proxy_url_list else None)
120
  try:
121
  background = BackgroundTask(client.close)
122
  r = await client.request(request.method, f"{base_url}/{path}", params=params, headers=headers,
123
  cookies=request_cookies, data=data, stream=True, allow_redirects=False)
124
+
125
+ if r.status_code == 302:
 
 
 
 
 
 
 
 
 
 
126
  return Response(status_code=302,
127
  headers={"Location": r.headers.get("Location").replace("chatgpt.com", origin_host)
 
 
128
  .replace("cdn.oaistatic.com", origin_host)
129
  .replace("https", petrol)}, background=background)
130
  elif 'stream' in r.headers.get("content-type", ""):
131
  return StreamingResponse(r.aiter_content(), media_type=r.headers.get("content-type", ""),
132
  background=background)
133
  else:
134
+ if "/backend-api/conversation" in path or "/register-websocket" in path:
135
  response = Response(content=(await r.atext()), media_type=r.headers.get("content-type"),
136
  status_code=r.status_code, background=background)
137
  else:
138
  content = ((await r.atext()).replace("chatgpt.com", origin_host)
 
 
139
  .replace("cdn.oaistatic.com", origin_host)
140
+ # .replace("files.oaiusercontent.com", origin_host)
141
  .replace("https", petrol))
142
  rheaders = dict(r.headers)
 
143
  content_type = rheaders.get("content-type", "")
144
+ cache_control = rheaders.get("cache-control", "")
145
+ expires = rheaders.get("expires", "")
146
  rheaders = {
147
  "cache-control": cache_control,
148
+ "content-type": content_type,
149
+ "expires": expires
150
  }
151
  response = Response(content=content, headers=rheaders,
152
  status_code=r.status_code, background=background)
 
 
 
 
 
 
 
 
 
153
  return response
154
  except Exception:
155
  await client.close()
requirements.txt CHANGED
@@ -8,4 +8,5 @@ websockets
8
  pillow
9
  pybase64
10
  jinja2
11
- APScheduler
 
 
8
  pillow
9
  pybase64
10
  jinja2
11
+ APScheduler
12
+ ua-generator
templates/chatgpt.html ADDED
The diff for this file is too large to render. See raw diff
 
utils/Client.py CHANGED
@@ -4,44 +4,41 @@ from curl_cffi.requests import AsyncSession
4
 
5
 
6
  class Client:
7
- def __init__(self, proxy=None, timeout=15, verify=True):
8
- self.proxies = {
9
- "http": proxy,
10
- "https": proxy,
11
- }
12
  self.timeout = timeout
13
  self.verify = verify
14
 
15
- self.impersonate = random.choice(['safari15_3'])
16
  # impersonate=self.impersonate
17
 
18
  # self.ja3 = ""
19
  # self.akamai = ""
20
  # ja3=self.ja3, akamai=self.akamai
21
- self.session = AsyncSession(proxies=self.proxies, timeout=self.timeout, verify=self.verify)
22
- self.session2 = AsyncSession(proxies=self.proxies, timeout=self.timeout, verify=self.verify)
23
 
24
  async def post(self, *args, **kwargs):
25
- r = await self.session.post(*args, impersonate=self.impersonate, **kwargs)
26
  return r
27
 
28
  async def post_stream(self, *args, headers=None, cookies=None, **kwargs):
29
  if self.session:
30
  headers = headers or self.session.headers
31
  cookies = cookies or self.session.cookies
32
- r = await self.session2.post(*args, headers=headers, cookies=cookies, impersonate=self.impersonate, **kwargs)
33
  return r
34
 
35
  async def get(self, *args, **kwargs):
36
- r = await self.session.get(*args, impersonate=self.impersonate, **kwargs)
37
  return r
38
 
39
  async def request(self, *args, **kwargs):
40
- r = await self.session.request(*args, impersonate=self.impersonate, **kwargs)
41
  return r
42
 
43
  async def put(self, *args, **kwargs):
44
- r = await self.session.put(*args, impersonate=self.impersonate, **kwargs)
45
  return r
46
 
47
  async def close(self):
 
4
 
5
 
6
  class Client:
7
+ def __init__(self, proxy=None, timeout=15, verify=True, impersonate='safari15_3'):
8
+ self.proxies = {"http": proxy, "https": proxy}
 
 
 
9
  self.timeout = timeout
10
  self.verify = verify
11
 
12
+ self.impersonate = impersonate
13
  # impersonate=self.impersonate
14
 
15
  # self.ja3 = ""
16
  # self.akamai = ""
17
  # ja3=self.ja3, akamai=self.akamai
18
+ self.session = AsyncSession(proxies=self.proxies, timeout=self.timeout, impersonate=self.impersonate, verify=self.verify)
19
+ self.session2 = AsyncSession(proxies=self.proxies, timeout=self.timeout, impersonate=self.impersonate, verify=self.verify)
20
 
21
  async def post(self, *args, **kwargs):
22
+ r = await self.session.post(*args, **kwargs)
23
  return r
24
 
25
  async def post_stream(self, *args, headers=None, cookies=None, **kwargs):
26
  if self.session:
27
  headers = headers or self.session.headers
28
  cookies = cookies or self.session.cookies
29
+ r = await self.session2.post(*args, headers=headers, cookies=cookies, **kwargs)
30
  return r
31
 
32
  async def get(self, *args, **kwargs):
33
+ r = await self.session.get(*args, **kwargs)
34
  return r
35
 
36
  async def request(self, *args, **kwargs):
37
+ r = await self.session.request(*args, **kwargs)
38
  return r
39
 
40
  async def put(self, *args, **kwargs):
41
+ r = await self.session.put(*args, **kwargs)
42
  return r
43
 
44
  async def close(self):
utils/config.py CHANGED
@@ -24,6 +24,7 @@ authorization = os.getenv('AUTHORIZATION', '').replace(' ', '')
24
  chatgpt_base_url = os.getenv('CHATGPT_BASE_URL', 'https://chatgpt.com').replace(' ', '')
25
  auth_key = os.getenv('AUTH_KEY', None)
26
  user_agents = os.getenv('USER_AGENTS', '[]')
 
27
 
28
  ark0se_token_url = os.getenv('ARK' + 'OSE_TOKEN_URL', '').replace(' ', '')
29
  if not ark0se_token_url:
@@ -37,7 +38,7 @@ turnstile_solver_url = os.getenv('TURNSTILE_SOLVER_URL', None)
37
  history_disabled = is_true(os.getenv('HISTORY_DISABLED', True))
38
  pow_difficulty = os.getenv('POW_DIFFICULTY', '000032')
39
  retry_times = int(os.getenv('RETRY_TIMES', 3))
40
- enable_gateway = is_true(os.getenv('ENABLE_GATEWAY', True))
41
  conversation_only = is_true(os.getenv('CONVERSATION_ONLY', False))
42
  enable_limit = is_true(os.getenv('ENABLE_LIMIT', True))
43
  upload_by_url = is_true(os.getenv('UPLOAD_BY_URL', False))
@@ -51,7 +52,7 @@ proxy_url_list = proxy_url.split(',') if proxy_url else []
51
  user_agents_list = ast.literal_eval(user_agents)
52
 
53
  logger.info("-" * 60)
54
- logger.info("Chat2Api 1.4.16 | https://github.com/lanqian528/chat2api")
55
  logger.info("-" * 60)
56
  logger.info("Environment variables:")
57
  logger.info("API_PREFIX: " + str(api_prefix))
@@ -71,4 +72,5 @@ logger.info("UPLOAD_BY_URL: " + str(upload_by_url))
71
  logger.info("CHECK_MODEL: " + str(check_model))
72
  logger.info("SCHEDULED_REFRESH: " + str(scheduled_refresh))
73
  logger.info("USER_AGENTS: " + str(user_agents_list))
 
74
  logger.info("-" * 60)
 
24
  chatgpt_base_url = os.getenv('CHATGPT_BASE_URL', 'https://chatgpt.com').replace(' ', '')
25
  auth_key = os.getenv('AUTH_KEY', None)
26
  user_agents = os.getenv('USER_AGENTS', '[]')
27
+ random_token = is_true(os.getenv('RANDOM_TOKEN', True))
28
 
29
  ark0se_token_url = os.getenv('ARK' + 'OSE_TOKEN_URL', '').replace(' ', '')
30
  if not ark0se_token_url:
 
38
  history_disabled = is_true(os.getenv('HISTORY_DISABLED', True))
39
  pow_difficulty = os.getenv('POW_DIFFICULTY', '000032')
40
  retry_times = int(os.getenv('RETRY_TIMES', 3))
41
+ enable_gateway = is_true(os.getenv('ENABLE_GATEWAY', False))
42
  conversation_only = is_true(os.getenv('CONVERSATION_ONLY', False))
43
  enable_limit = is_true(os.getenv('ENABLE_LIMIT', True))
44
  upload_by_url = is_true(os.getenv('UPLOAD_BY_URL', False))
 
52
  user_agents_list = ast.literal_eval(user_agents)
53
 
54
  logger.info("-" * 60)
55
+ logger.info("Chat2Api 1.5.6 | https://github.com/lanqian528/chat2api")
56
  logger.info("-" * 60)
57
  logger.info("Environment variables:")
58
  logger.info("API_PREFIX: " + str(api_prefix))
 
72
  logger.info("CHECK_MODEL: " + str(check_model))
73
  logger.info("SCHEDULED_REFRESH: " + str(scheduled_refresh))
74
  logger.info("USER_AGENTS: " + str(user_agents_list))
75
+ logger.info("RANDOM_TOKEN: " + str(random_token))
76
  logger.info("-" * 60)