Merge pull request #201 from lanqian528/dev
Some checks failed
Build Docker Image / main (push) Has been cancelled

Dev to Main
This commit is contained in:
LanQian 2024-11-30 21:57:48 +08:00 committed by GitHub
commit f7b3952b50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 93 additions and 77 deletions

View File

@ -8,6 +8,9 @@
🔍 回复格式与真实 API 完全一致,适配几乎所有客户端
👮 配套用户管理端[Chat-Share](https://github.com/h88782481/Chat-Share)使用前需提前配置好环境变量ENABLE_GATEWAY设置为TrueAUTO_SEED设置为False
## 交流群
[https://t.me/chat2api](https://t.me/chat2api)

View File

@ -8,9 +8,10 @@ from starlette.concurrency import run_in_threadpool
from api.files import get_image_size, get_file_extension, determine_file_use_case
from api.models import model_proxy
from chatgpt.authorization import get_req_token, verify_token, get_fp
from chatgpt.authorization import get_req_token, verify_token
from chatgpt.chatFormat import api_messages_to_chat, stream_response, format_not_stream_response, head_process_response
from chatgpt.chatLimit import check_is_limit, handle_request_limit
from chatgpt.fp import get_fp
from chatgpt.proofofWork import get_config, get_dpl, get_answer_token, get_requirements_token
from utils.Client import Client
@ -52,10 +53,10 @@ class ChatService:
self.access_token = None
self.account_id = None
self.fp = get_fp(self.req_token)
self.proxy_url = self.fp.get("proxy_url")
self.fp = get_fp(self.req_token).copy()
self.proxy_url = self.fp.pop("proxy_url", None)
self.impersonate = self.fp.pop("impersonate", "safari15_3")
self.user_agent = self.fp.get("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0")
self.impersonate = self.fp.get("impersonate", "safari15_3")
logger.info(f"Request token: {self.req_token}")
logger.info(f"Request proxy: {self.proxy_url}")
logger.info(f"Request UA: {self.user_agent}")
@ -86,7 +87,6 @@ class ChatService:
self.s = Client(proxy=self.proxy_url, impersonate=self.impersonate)
self.oai_device_id = str(uuid.uuid4())
self.persona = None
self.ark0se_token = None
self.proof_token = None
@ -100,19 +100,16 @@ class ChatService:
'accept-encoding': 'gzip, deflate, br, zstd',
'accept-language': 'en-US,en;q=0.9',
'content-type': 'application/json',
'oai-device-id': self.oai_device_id,
'oai-language': oai_language,
'origin': self.host_url,
'priority': 'u=1, i',
'referer': f'{self.host_url}/',
'sec-ch-ua': self.fp.get("sec-ch-ua", '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"'),
'sec-ch-ua-mobile': self.fp.get("sec-ch-ua-mobile", "?0"),
'sec-ch-ua-platform': self.fp.get("sec-ch-ua-platform", '"Windows"'),
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': self.user_agent
'sec-fetch-site': 'same-origin'
}
self.base_headers.update(self.fp)
if self.access_token:
self.base_url = self.host_url + "/backend-api"
self.base_headers['authorization'] = f'Bearer {self.access_token}'
@ -225,7 +222,7 @@ class ChatService:
if not self.ark0se_token_url:
raise HTTPException(status_code=403, detail="Ark0se service required")
ark0se_dx = ark0se.get("dx")
ark0se_client = Client(impersonate=self.fp.get("impersonate", "safari15_3"))
ark0se_client = Client(impersonate=self.impersonate)
try:
r2 = await ark0se_client.post(
url=self.ark0se_token_url, json={"blob": ark0se_dx, "method": ark0se_method}, timeout=15

View File

@ -1,11 +1,7 @@
import asyncio
import json
import random
import uuid
import ua_generator
from ua_generator.options import Options
from ua_generator.data.version import VersionRange
from fastapi import HTTPException
import utils.configs as configs
@ -47,51 +43,6 @@ def get_req_token(req_token, seed=None):
return globals.seed_map[seed]["token"]
def get_fp(req_token):
fp = globals.fp_map.get(req_token, {})
if fp and fp.get("user-agent") and fp.get("impersonate"):
if "proxy_url" in fp.keys() and fp["proxy_url"] is None and fp["proxy_url"] not in configs.proxy_url_list:
fp["proxy_url"] = random.choice(configs.proxy_url_list) if configs.proxy_url_list else None
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
if globals.impersonate_list and "impersonate" in fp.keys() and fp["impersonate"] not in globals.impersonate_list:
fp["impersonate"] = random.choice(globals.impersonate_list)
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
if configs.user_agents_list and "user-agent" in fp.keys() and fp["user-agent"] not in configs.user_agents_list:
fp["user-agent"] = random.choice(configs.user_agents_list)
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
fp = {k.lower(): v for k, v in fp.items()}
return fp
else:
options = Options(version_ranges={
'chrome': VersionRange(min_version=124),
'edge': VersionRange(min_version=124),
})
ua = ua_generator.generate(device='desktop', browser=('chrome', 'edge', 'firefox', 'safari'),
platform=('windows', 'macos'), options=options)
fp = {
"user-agent": ua.text if not configs.user_agents_list else random.choice(configs.user_agents_list),
"sec-ch-ua-platform": ua.ch.platform,
"sec-ch-ua": ua.ch.brands,
"sec-ch-ua-mobile": ua.ch.mobile,
"impersonate": random.choice(globals.impersonate_list),
"proxy_url": random.choice(configs.proxy_url_list) if configs.proxy_url_list else None,
"oai-device-id": str(uuid.uuid4())
}
if not req_token:
return fp
else:
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
return fp
async def verify_token(req_token):
if not req_token:
if configs.authorization_list:

61
chatgpt/fp.py Normal file
View File

@ -0,0 +1,61 @@
import json
import random
import uuid
import ua_generator
from ua_generator.data.version import VersionRange
from ua_generator.options import Options
import utils.globals as globals
from utils import configs
def get_fp(req_token):
fp = globals.fp_map.get(req_token, {})
if fp and fp.get("user-agent") and fp.get("impersonate"):
if "proxy_url" in fp.keys() and (fp["proxy_url"] is None or fp["proxy_url"] not in configs.proxy_url_list):
fp["proxy_url"] = random.choice(configs.proxy_url_list) if configs.proxy_url_list else None
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
if globals.impersonate_list and "impersonate" in fp.keys() and fp["impersonate"] not in globals.impersonate_list:
fp["impersonate"] = random.choice(globals.impersonate_list)
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
if configs.user_agents_list and "user-agent" in fp.keys() and fp["user-agent"] not in configs.user_agents_list:
fp["user-agent"] = random.choice(configs.user_agents_list)
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
fp = {k.lower(): v for k, v in fp.items()}
return fp
else:
options = Options(version_ranges={
'chrome': VersionRange(min_version=124),
'edge': VersionRange(min_version=124),
})
ua = ua_generator.generate(
device=configs.device_tuple if configs.device_tuple else ('desktop'),
browser=configs.browser_tuple if configs.browser_tuple else ('chrome', 'edge', 'firefox', 'safari'),
platform=configs.platform_tuple if configs.platform_tuple else ('windows', 'macos'),
options=options
)
fp = {
"user-agent": ua.text if not configs.user_agents_list else random.choice(configs.user_agents_list),
"impersonate": random.choice(globals.impersonate_list),
"proxy_url": random.choice(configs.proxy_url_list) if configs.proxy_url_list else None,
"oai-device-id": str(uuid.uuid4())
}
if ua.device == "desktop" and ua.browser in ("chrome", "edge"):
fp["sec-ch-ua-platform"] = ua.ch.platform
fp["sec-ch-ua"] = ua.ch.brands
fp["sec-ch-ua-mobile"] = ua.ch.mobile
if not req_token:
return fp
else:
globals.fp_map[req_token] = fp
with open(globals.FP_FILE, "w", encoding="utf-8") as f:
json.dump(globals.fp_map, f, indent=4)
return fp

View File

@ -11,7 +11,8 @@ from starlette.concurrency import run_in_threadpool
import utils.globals as globals
from app import app
from chatgpt.authorization import verify_token, get_fp
from chatgpt.authorization import verify_token
from chatgpt.fp import get_fp
from chatgpt.proofofWork import get_answer_token, get_config, get_requirements_token
from gateway.chatgpt import chatgpt_html
from gateway.reverseProxy import chatgpt_reverse_proxy, content_generator, get_real_req_token, headers_reject_list
@ -252,11 +253,10 @@ if no_sentinel:
token = request.headers.get("Authorization", "").replace("Bearer ", "")
req_token = await get_real_req_token(token)
access_token = await verify_token(req_token)
fp = get_fp(req_token)
fp = get_fp(req_token).copy()
proxy_url = fp.pop("proxy_url", None)
impersonate = fp.pop("impersonate", "safari15_3")
user_agent = fp.get("user-agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0")
user_agent = fp.get("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0")
host_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
proof_token = None
@ -264,14 +264,10 @@ if no_sentinel:
headers = {
key: value for key, value in request.headers.items()
if (key.lower() not in ["host", "origin", "referer", "priority",
"oai-device-id"] and key.lower() not in headers_reject_list)
if (key.lower() not in ["host", "origin", "referer", "priority", "sec-ch-ua-platform", "sec-ch-ua", "sec-ch-ua-mobile", "oai-device-id"] and key.lower() not in headers_reject_list)
}
headers.update(fp)
headers.update({
"authorization": f"Bearer {access_token}",
"oai-device-id": fp.get("oai-device-id", str(uuid.uuid4()))
})
headers.update({"authorization": f"Bearer {access_token}"})
client = Client(proxy=proxy_url, impersonate=impersonate)

View File

@ -9,7 +9,8 @@ from fastapi.responses import StreamingResponse, Response
from starlette.background import BackgroundTask
import utils.globals as globals
from chatgpt.authorization import verify_token, get_req_token, get_fp
from chatgpt.authorization import verify_token, get_req_token
from chatgpt.fp import get_fp
from utils.Client import Client
from utils.Logger import logger
from utils.configs import chatgpt_base_url_list
@ -173,7 +174,7 @@ async def chatgpt_reverse_proxy(request: Request, path: str):
token = request.cookies.get("token", "")
req_token = await get_real_req_token(token)
fp = get_fp(req_token)
fp = get_fp(req_token).copy()
proxy_url = fp.pop("proxy_url", None)
impersonate = fp.pop("impersonate", "safari15_3")
user_agent = fp.get("user-agent")

View File

@ -9,7 +9,8 @@ from fastapi.security import HTTPAuthorizationCredentials
import utils.globals as globals
from app import app, security_scheme
from chatgpt.authorization import get_fp, verify_token
from chatgpt.authorization import verify_token
from chatgpt.fp import get_fp
from gateway.reverseProxy import get_real_req_token
from utils.Client import Client
from utils.Logger import logger
@ -127,13 +128,13 @@ async def chatgpt_account_check(access_token):
host_url = random.choice(chatgpt_base_url_list) if chatgpt_base_url_list else "https://chatgpt.com"
req_token = await get_real_req_token(access_token)
access_token = await verify_token(req_token)
fp = get_fp(req_token)
fp = get_fp(req_token).copy()
proxy_url = fp.pop("proxy_url", None)
impersonate = fp.pop("impersonate", "safari15_3")
headers = base_headers.copy()
headers.update({"authorization": f"Bearer {access_token}"})
headers.update(fp)
headers.update({"authorization": f"Bearer {access_token}"})
client = Client(proxy=proxy_url, impersonate=impersonate)
r = await client.get(f"{host_url}/backend-api/models?history_and_training_disabled=false", headers=headers,

View File

@ -32,6 +32,9 @@ proxy_url = os.getenv('PROXY_URL', '').replace(' ', '')
export_proxy_url = os.getenv('EXPORT_PROXY_URL', None)
impersonate_list_str = os.getenv('IMPERSONATE', '[]')
user_agents_list_str = os.getenv('USER_AGENTS', '[]')
device_tuple_str = os.getenv('DEVICE_TUPLE', '()')
browser_tuple_str = os.getenv('BROWSER_TUPLE', '()')
platform_tuple_str = os.getenv('PLATFORM_TUPLE', '()')
cf_file_url = os.getenv('CF_FILE_URL', None)
turnstile_solver_url = os.getenv('TURNSTILE_SOLVER_URL', None)
@ -53,6 +56,9 @@ ark0se_token_url_list = ark0se_token_url.split(',') if ark0se_token_url else []
proxy_url_list = proxy_url.split(',') if proxy_url else []
impersonate_list = ast.literal_eval(impersonate_list_str)
user_agents_list = ast.literal_eval(user_agents_list_str)
device_tuple = ast.literal_eval(device_tuple_str)
browser_tuple = ast.literal_eval(browser_tuple_str)
platform_tuple = ast.literal_eval(platform_tuple_str)
enable_gateway = is_true(os.getenv('ENABLE_GATEWAY', False))
auto_seed = is_true(os.getenv('AUTO_SEED', True))

View File

@ -1 +1 @@
1.7.2
v1.7.3-beta1