From fd1ad1957ed264deeb37cfe06b123bc20a9ae061 Mon Sep 17 00:00:00 2001 From: lanqian528 <5499636+lanqian528@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:56:45 +0800 Subject: [PATCH] v1.5.9 merge pr --- chat2api.py | 139 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 17 deletions(-) diff --git a/chat2api.py b/chat2api.py index 887ad12..1cff187 100644 --- a/chat2api.py +++ b/chat2api.py @@ -1,4 +1,5 @@ import asyncio +import time import types import warnings @@ -10,13 +11,14 @@ from fastapi.responses import StreamingResponse, JSONResponse from fastapi.security import OAuth2PasswordBearer from fastapi.templating import Jinja2Templates from starlette.background import BackgroundTask +from starlette.responses import RedirectResponse, Response from chatgpt.ChatService import ChatService -from chatgpt.authorization import refresh_all_tokens +from chatgpt.authorization import refresh_all_tokens, verify_token, get_req_token import chatgpt.globals as globals from chatgpt.reverseProxy import chatgpt_reverse_proxy from utils.Logger import logger -from utils.config import api_prefix, scheduled_refresh +from utils.config import api_prefix, scheduled_refresh, enable_gateway from utils.retry import async_retry warnings.filterwarnings("ignore") @@ -38,7 +40,8 @@ app.add_middleware( @app.on_event("startup") async def app_start(): if scheduled_refresh: - scheduler.add_job(id='refresh', func=refresh_all_tokens, trigger='cron', hour=3, minute=0, day='*/4', kwargs={'force_refresh': True}) + scheduler.add_job(id='refresh', func=refresh_all_tokens, trigger='cron', hour=3, minute=0, day='*/4', + kwargs={'force_refresh': True}) scheduler.start() asyncio.get_event_loop().call_later(0, lambda: asyncio.create_task(refresh_all_tokens(force_refresh=False))) @@ -111,17 +114,6 @@ async def upload_post(text: str = Form(...)): return {"status": "success", "tokens_count": tokens_count} -@app.get(f"/{api_prefix}/tokens/add/{{token}}" if api_prefix else "/tokens/add/{token}") -async def add_token(token: str): - if token.strip() and not token.startswith("#"): - globals.token_list.append(token.strip()) - with open("data/token.txt", "a", encoding="utf-8") as f: - f.write(token.strip() + "\n") - logger.info(f"Token count: {len(globals.token_list)}, Error token count: {len(globals.error_token_list)}") - tokens_count = len(set(globals.token_list) - set(globals.error_token_list)) - return {"status": "success", "tokens_count": tokens_count} - - @app.post(f"/{api_prefix}/tokens/clear" if api_prefix else "/tokens/clear") async def upload_post(): globals.token_list.clear() @@ -139,6 +131,119 @@ async def error_tokens(): return {"status": "success", "error_tokens": error_tokens_list} -@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) -async def reverse_proxy(request: Request, path: str): - return await chatgpt_reverse_proxy(request, path) +@app.get(f"/{api_prefix}/tokens/add/{{token}}" if api_prefix else "/tokens/add/{token}") +async def add_token(token: str): + if token.strip() and not token.startswith("#"): + globals.token_list.append(token.strip()) + with open("data/token.txt", "a", encoding="utf-8") as f: + f.write(token.strip() + "\n") + logger.info(f"Token count: {len(globals.token_list)}, Error token count: {len(globals.error_token_list)}") + tokens_count = len(set(globals.token_list) - set(globals.error_token_list)) + return {"status": "success", "tokens_count": tokens_count} + + +if enable_gateway: + @app.get("/", response_class=HTMLResponse) + async def chatgpt_html(request: Request): + token = request.query_params.get("token") + if not token: + token = request.cookies.get("token") + if not token: + return await login_html(request) + + response = templates.TemplateResponse("chatgpt.html", {"request": request, "token": token}) + response.set_cookie("token", value=token) + return response + + @app.get("/login", response_class=HTMLResponse) + async def login_html(request: Request): + response = templates.TemplateResponse("login.html", {"request": request}) + return response + + + @app.get("/backend-api/gizmos/bootstrap") + async def get_gizmos_bootstrap(): + return {"gizmos": []} + + + # @app.get("/backend-api/conversations") + # async def get_conversations(): + # return {"items": [], "total": 0, "limit": 28, "offset": 0, "has_missing_conversations": False} + + # @app.patch("/backend-api/conversations") + # async def get_conversations(): + # return {"success": True, "message": None} + + + @app.get("/backend-api/me") + async def get_me(): + created = int(time.time()) + return { + "object": "user", + "id": "org-chatgpt", + "email": "chatgpt@openai.com", + "name": "ChatGPT", + "picture": "https://cdn.auth0.com/avatars/ai.png", + "created": created, + "phone_number": None, + "mfa_flag_enabled": False, + "amr": [], + "groups": [], + "orgs": { + "object": "list", + "data": [ + { + "object": "organization", + "id": "org-chatgpt", + "created": 1715641300, + "title": "Personal", + "name": "user-chatgpt", + "description": "Personal org for chatgpt@openai.com", + "personal": True, + "settings": {}, + "parent_org_id": None, + "is_default": False, + "role": "owner", + "is_scale_tier_authorized_purchaser": None, + "is_scim_managed": False, + "projects": { + "object": "list", + "data": [] + }, + "groups": [], + "geography": None + } + ] + }, + "has_payg_project_spend_limit": None + } + + + banned_paths = ["backend-api/accounts/logout_all", "backend-api/accounts/deactivate", + "backend-api/user_system_messages"] + redirect_paths = ["auth/logout"] + chatgpt_paths = ["c/"] + + + @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) + async def reverse_proxy(request: Request, path: str): + for chatgpt_path in chatgpt_paths: + if chatgpt_path in path: + return await chatgpt_html(request) + + for banned_path in banned_paths: + if banned_path in path: + return Response(status_code=404) + + for redirect_path in redirect_paths: + if redirect_path in path: + redirect_url = str(request.base_url) + response = RedirectResponse(url=f"{redirect_url}", status_code=302) + response.delete_cookie("token") + return response + + return await chatgpt_reverse_proxy(request, path) +else: + @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) + async def reverse_proxy(): + raise HTTPException(status_code=404, detail="Gateway is disabled")