Download chat2api.py from Rfym21/Chat2API: direct link, hf CLI and curl.
- Browser
- Download file 10.4 kB
-
https://huggingface.co/spaces/Rfym21/Chat2API/resolve/bcb45841cfafb83ca241176763dab7b9f2a33e9b/chat2api.py
- Command line
-
hf download hf://spaces/Rfym21/Chat2API@bcb45841cfafb83ca241176763dab7b9f2a33e9b/chat2api.py
-
curl -L -o chat2api.py https://huggingface.co/spaces/Rfym21/Chat2API/resolve/bcb45841cfafb83ca241176763dab7b9f2a33e9b/chat2api.py
10.4 kB
| import asyncio | |
| import time | |
| import types | |
| import warnings | |
| from apscheduler.schedulers.asyncio import AsyncIOScheduler | |
| from fastapi import FastAPI, Request, Depends, HTTPException, Form | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import HTMLResponse | |
| 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, 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, enable_gateway | |
| from utils.retry import async_retry | |
| warnings.filterwarnings("ignore") | |
| app = FastAPI() | |
| scheduler = AsyncIOScheduler() | |
| templates = Jinja2Templates(directory="templates") | |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token", auto_error=False) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| 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.start() | |
| asyncio.get_event_loop().call_later(0, lambda: asyncio.create_task(refresh_all_tokens(force_refresh=False))) | |
| async def to_send_conversation(request_data, req_token): | |
| chat_service = ChatService(req_token) | |
| try: | |
| await chat_service.set_dynamic_data(request_data) | |
| await chat_service.get_chat_requirements() | |
| return chat_service | |
| except HTTPException as e: | |
| await chat_service.close_client() | |
| raise HTTPException(status_code=e.status_code, detail=e.detail) | |
| except Exception as e: | |
| await chat_service.close_client() | |
| logger.error(f"Server error, {str(e)}") | |
| raise HTTPException(status_code=500, detail="Server error") | |
| async def process(request_data, req_token): | |
| chat_service = await to_send_conversation(request_data, req_token) | |
| await chat_service.prepare_send_conversation() | |
| res = await chat_service.send_conversation() | |
| return chat_service, res | |
| async def send_conversation(request: Request, req_token: str = Depends(oauth2_scheme)): | |
| try: | |
| request_data = await request.json() | |
| except Exception: | |
| raise HTTPException(status_code=400, detail={"error": "Invalid JSON body"}) | |
| chat_service, res = await async_retry(process, request_data, req_token) | |
| try: | |
| if isinstance(res, types.AsyncGeneratorType): | |
| background = BackgroundTask(chat_service.close_client) | |
| return StreamingResponse(res, media_type="text/event-stream", background=background) | |
| else: | |
| background = BackgroundTask(chat_service.close_client) | |
| return JSONResponse(res, media_type="application/json", background=background) | |
| except HTTPException as e: | |
| await chat_service.close_client() | |
| if e.status_code == 500: | |
| logger.error(f"Server error, {str(e)}") | |
| raise HTTPException(status_code=500, detail="Server error") | |
| raise HTTPException(status_code=e.status_code, detail=e.detail) | |
| except Exception as e: | |
| await chat_service.close_client() | |
| logger.error(f"Server error, {str(e)}") | |
| raise HTTPException(status_code=500, detail="Server error") | |
| async def upload_html(request: Request): | |
| tokens_count = len(set(globals.token_list) - set(globals.error_token_list)) | |
| return templates.TemplateResponse("tokens.html", | |
| {"request": request, "api_prefix": api_prefix, "tokens_count": tokens_count}) | |
| async def upload_post(text: str = Form(...)): | |
| lines = text.split("\n") | |
| for line in lines: | |
| if line.strip() and not line.startswith("#"): | |
| globals.token_list.append(line.strip()) | |
| with open("data/token.txt", "a", encoding="utf-8") as f: | |
| f.write(line.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} | |
| async def upload_post(): | |
| globals.token_list.clear() | |
| globals.error_token_list.clear() | |
| with open("data/token.txt", "w", encoding="utf-8") as f: | |
| pass | |
| 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} | |
| async def error_tokens(): | |
| error_tokens_list = list(set(globals.error_token_list)) | |
| return {"status": "success", "error_tokens": error_tokens_list} | |
| 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: | |
| 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 | |
| async def login_html(request: Request): | |
| response = templates.TemplateResponse("login.html", {"request": request}) | |
| return response | |
| 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} | |
| 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", | |
| "backend-api/memories", | |
| "backend-api/settings/clear_account_user_memory" | |
| ] | |
| redirect_paths = ["auth/logout"] | |
| chatgpt_paths = ["c/"] | |
| 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: | |
| async def reverse_proxy(): | |
| raise HTTPException(status_code=404, detail="Gateway is disabled") | |