diff --git a/README.md b/README.md index 93a4a41..93ca910 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ https://t.me/chat2api > - [x] 上传图片、文件 (格式为API对应格式,支持url和base64) > TODO +> - [ ] claude2api > - [ ] 暂无,欢迎提 issue - ## 部署 ### (推荐) zeabur部署 @@ -107,7 +107,8 @@ curl --location 'http://127.0.0.1:5005/v1/chat/completions' \ ## 常见问题 > - 错误代码: -> - `401`:当前IP不支持免登录,请尝试更换IP地址,或者在环境变量 `PROXY_URL` 中设置代理。 + > +- `401`:当前IP不支持免登录,请尝试更换IP地址,或者在环境变量 `PROXY_URL` 中设置代理。 > - `403`:当前IP地址被 CF 盾拦截,请尝试更换IP地址,或者在环境变量 `PROXY_URL` 中设置代理。 > - `429`:当前IP请求1小时内请求超过限制,请稍后再试,或更换ip。 > - `500`:服务器内部错误,请求失败。 @@ -116,7 +117,7 @@ curl --location 'http://127.0.0.1:5005/v1/chat/completions' \ ## 使用GPT4 > #### 目前支持外部服务提供 ArkoseToken -> +> > #### 推荐使用 docker-compose 方式部署, 已内置 Arkose 服务 1. 设置环境变量ARKOSE_TOKEN_URL @@ -126,6 +127,7 @@ curl --location 'http://127.0.0.1:5005/v1/chat/completions' \ 3. 请按照以下格式提供外部服务: - 请求体: + ```request body { "blob": "rFYaxQNEApDlx/Db.KyrE79pAAFBs70CYtbM4pMNUsc7jIkLGdiDs7vziHRGe78bqWXDo0AYyq2A10qIlcTt89lBYXJqCbONC/nD8C199pEZ/c9ocVKKtM27jZQ7fyOpWd9p5qjKeXT4xEGBFpoE3Re1DwdQeijYp7VMJQyw7RYN+IDB1QEx3aKSO6aTI+ivnhw9ztfn/p1SkvAyyOhur/ArF08WQ+rXQpxpttaSQlzMsIwlYbuUUuYE2f9JrQaYG7qip1DKvju111P6wTNy4QVlMXG32VrzaOWh4nmQ0lOcZ1DmN6u2aeJZotffHV2zOOQAqqnParidTbN+qFre2t77ZwBuGKGqLyT8LeOp02GdFwcyw0kkeX+L7vwYAzBpjA5ky0r0X+i8HpzWt8QCyWzEW9kHn9LLCTwg2MOumzjb66Ad4WDe+C1bAcOKuEyXiYh+a1cWZAOdzEuxEg90yCfI7DZR94BsoDR85gEC/Og88i098u5HV7hZZEOQ6J8fmi68FSyPkN7oLCmBsZCMAZqzapNP/MkeIMExrdw7Jf/PtMrZN4bwM56mWfyIJf5h/zXu8PUajVwE9Pj/M5VtB0spZg49JNeHExosVCAB0C0JW+T8vEIwoqiY4pRQ0lbMHTQZFpU2xURTgcgh+m6g1SEYR1FY3de1XnzfiTQq1RTNJPydj5xpt6r6okr8yIJdRhmVXlQI+pS7vi3+Lls2hnpr7L+l1mcUIMPZNBCs3AUFJNpp6SwQjZkPvKggg1p+uS6PdvKRizM9O9+FKc103AhuSia8KTrvU8tWhBhCzIHCD4LNfnkjuBWSdbDttva4AEXUoPuKkQCWaBzq4lQPUIHFOM9HmNe738vVkNdAuOYffxDNegcpIxLVgZGfbgLQ=" @@ -133,6 +135,7 @@ curl --location 'http://127.0.0.1:5005/v1/chat/completions' \ ``` - 响应体: + ```response body { "token": "45017c7bb17115f36.7290869304|r=ap-southeast-1|meta=3|metabgclr=transparent|metaiconclr=%23757575|guitextcolor=%23000000|pk=0A1D34FC-659D-4E23-B17B-694DCFCF6A6C|at=40|sup=1|rid=3|ag=101|cdn_url=https%3A%2F%2Ftcr9i.openai.com%2Fcdn%2Ffc|lurl=https%3A%2F%2Faudio-ap-southeast-1.arkoselabs.com|surl=https%3A%2F%2Ftcr9i.openai.com|smurl=https%3A%2F%2Ftcr9i.openai.com%2Fcdn%2Ffc%2Fassets%2Fstyle-manager" @@ -148,7 +151,7 @@ curl --location 'http://127.0.0.1:5005/v1/chat/completions' \ ``` AUTHORIZATION=your_first_token, your_second_token // 使用免登3.5的Bearer token,不设置则无需Bearer token CHATGPT_BASE_URL=https://chat.openai.com // ChatGPT网关地址 -HISTORY_DISABLED=true // 是否保存聊天记录并返回 conversation_id (beta),true为不保存 +HISTORY_DISABLED=true // 是否不保存聊天记录并返回 conversation_id (beta),true为不保存 PROXY_URL=your_first_proxy, your_second_proxy // 代理url,多个代理用逗号分隔 ARKOSE_TOKEN_URL=https://arkose.example.com/token // 获取Arkose token的地址,上文有提供说明 RETRY_TIMES=3 // 重试次数 diff --git a/api/files.py b/api/files.py index 0008d04..0db60c7 100644 --- a/api/files.py +++ b/api/files.py @@ -6,7 +6,6 @@ from PIL import Image from utils.Client import Client - async def get_file_content(url): if url.startswith("data:"): mime_type, base64_data = url.split(';')[0].split(':')[1], url.split(',')[1] @@ -75,4 +74,4 @@ async def get_file_extension(mime_type): "text/x-script.python": ".py", # 其他 MIME 类型和扩展名... } - return extension_mapping.get(mime_type, "") \ No newline at end of file + return extension_mapping.get(mime_type, "") diff --git a/api/models.py b/api/models.py index 04aeb69..ebdaeff 100644 --- a/api/models.py +++ b/api/models.py @@ -19,4 +19,4 @@ model_system_fingerprint = { "gpt-4-1106-preview": ["fp_e467c31c3d", "fp_d986a8d1ba", "fp_99a5a401bb", "fp_123d5a9f90", "fp_0d1affc7a6", "fp_5c95a4634e"], "gpt-4-turbo-2024-04-09": ["fp_d1bac968b4"] -} \ No newline at end of file +} diff --git a/api/tokens.py b/api/tokens.py index 5a5dac8..1dfd858 100644 --- a/api/tokens.py +++ b/api/tokens.py @@ -92,4 +92,4 @@ async def split_tokens_from_content(content, max_tokens, model=None): content = encoding.decode(encoded_content[:max_tokens]) return content, max_tokens, "length" else: - return content, len_encoded_content, "stop" \ No newline at end of file + return content, len_encoded_content, "stop" diff --git a/chatgpt/ChatService.py b/chatgpt/ChatService.py index fe6c7e8..b7249ca 100644 --- a/chatgpt/ChatService.py +++ b/chatgpt/ChatService.py @@ -5,15 +5,15 @@ import uuid import websockets from fastapi import HTTPException +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.chatFormat import api_messages_to_chat, stream_response, wss_stream_response, format_not_stream_response -from chatgpt.proofofwork import calc_proof_token, chat_requirements_body +from chatgpt.proofofWork import calc_proof_token, chat_requirements_body from utils.Client import Client from utils.Logger import Logger from utils.config import proxy_url_list, chatgpt_base_url_list, arkose_token_url_list, history_disabled -from starlette.concurrency import run_in_threadpool class ChatService: @@ -208,9 +208,7 @@ class ChatService: if stream and isinstance(wss_r, types.AsyncGeneratorType): return stream_response(self, wss_r, self.target_model, self.max_tokens) else: - return await format_not_stream_response( - stream_response(self, wss_r, self.target_model, self.max_tokens), self.prompt_tokens, - self.max_tokens, self.target_model) + return await format_not_stream_response(stream_response(self, wss_r, self.target_model, self.max_tokens), self.prompt_tokens, self.max_tokens, self.target_model) finally: if not isinstance(wss_r, types.AsyncGeneratorType): await self.ws.close() diff --git a/chatgpt/chatFormat.py b/chatgpt/chatFormat.py index d8c05b0..ef847db 100644 --- a/chatgpt/chatFormat.py +++ b/chatgpt/chatFormat.py @@ -1,7 +1,6 @@ import asyncio import base64 import json -import os import random import string import time diff --git a/chatgpt/proofofwork.py b/chatgpt/proofofWork.py similarity index 100% rename from chatgpt/proofofwork.py rename to chatgpt/proofofWork.py diff --git a/chatgpt/reverseProxy.py b/chatgpt/reverseProxy.py index d80bc9a..3849bc6 100644 --- a/chatgpt/reverseProxy.py +++ b/chatgpt/reverseProxy.py @@ -1,4 +1,5 @@ import random + from fastapi import Request, HTTPException from fastapi.responses import StreamingResponse, Response from starlette.background import BackgroundTask @@ -102,8 +103,7 @@ async def chatgpt_reverse_proxy(request: Request, path: str): client = Client(proxy=random.choice(proxy_url_list) if proxy_url_list else None) r = None try: - r = await client.request(request.method, f"{base_url}/{path}", params=params, headers=headers, cookies=cookies, - data=data, stream=True) + r = await client.request(request.method, f"{base_url}/{path}", params=params, headers=headers, cookies=cookies, data=data, stream=True) if r.status_code == 302: return Response(status_code=302, headers={"Location": r.headers.get("Location")}) elif 'stream' in r.headers.get("content-type", ""): diff --git a/utils/Client.py b/utils/Client.py index 5657d0c..ff90f10 100644 --- a/utils/Client.py +++ b/utils/Client.py @@ -45,4 +45,4 @@ class Client: await self.session.close() self.session = None except Exception: - pass \ No newline at end of file + pass diff --git a/utils/Logger.py b/utils/Logger.py index 4730029..e9aa15e 100644 --- a/utils/Logger.py +++ b/utils/Logger.py @@ -21,4 +21,4 @@ class Logger: logging.debug("\033[0;37m" + str(message) + "\033[0m") -logger = Logger() \ No newline at end of file +logger = Logger() diff --git a/utils/retry.py b/utils/retry.py index b74ce6e..7f103eb 100644 --- a/utils/retry.py +++ b/utils/retry.py @@ -1,6 +1,6 @@ -from utils.Logger import logger from fastapi import HTTPException +from utils.Logger import logger from utils.config import retry_times