Spaces:
Runtime error
Runtime error
| import asyncio | |
| import json | |
| from concurrent.futures import ThreadPoolExecutor | |
| from typing import List | |
| import g4f | |
| from fastapi import FastAPI, HTTPException, Header | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import StreamingResponse | |
| from pydantic import BaseModel | |
| # ===================================== | |
| # CONFIG | |
| # ===================================== | |
| API_KEY = "sk-your-secret-key" | |
| executor = ThreadPoolExecutor(max_workers=5) | |
| # ===================================== | |
| # APP | |
| # ===================================== | |
| app = FastAPI( | |
| title="AI Gateway" | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ===================================== | |
| # MODELS | |
| # ===================================== | |
| class Message(BaseModel): | |
| role: str | |
| content: str | |
| class ChatRequest(BaseModel): | |
| model: str = "gpt-4o-mini" | |
| messages: List[Message] | |
| stream: bool = False | |
| # ===================================== | |
| # AUTH | |
| # ===================================== | |
| def verify_api_key(auth: str): | |
| if not auth: | |
| raise HTTPException( | |
| status_code=401, | |
| detail="Missing Authorization Header" | |
| ) | |
| if not auth.startswith("Bearer "): | |
| raise HTTPException( | |
| status_code=401, | |
| detail="Invalid Authorization" | |
| ) | |
| token = auth.replace("Bearer ", "") | |
| if token != API_KEY: | |
| raise HTTPException( | |
| status_code=403, | |
| detail="Invalid API Key" | |
| ) | |
| # ===================================== | |
| # GENERATE | |
| # ===================================== | |
| def generate(model, messages): | |
| response = g4f.ChatCompletion.create( | |
| model=model, | |
| messages=messages | |
| ) | |
| return response | |
| # ===================================== | |
| # STREAM | |
| # ===================================== | |
| async def stream_generate(model, messages): | |
| loop = asyncio.get_event_loop() | |
| response = await loop.run_in_executor( | |
| executor, | |
| lambda: g4f.ChatCompletion.create( | |
| model=model, | |
| messages=messages, | |
| stream=True | |
| ) | |
| ) | |
| for chunk in response: | |
| if chunk: | |
| payload = { | |
| "choices": [ | |
| { | |
| "delta": { | |
| "content": chunk | |
| } | |
| } | |
| ] | |
| } | |
| yield f"data: {json.dumps(payload)}\\n\\n" | |
| yield "data: [DONE]\\n\\n" | |
| # ===================================== | |
| # HOME | |
| # ===================================== | |
| async def home(): | |
| return { | |
| "status": "online" | |
| } | |
| # ===================================== | |
| # CHAT | |
| # ===================================== | |
| async def chat( | |
| req: ChatRequest, | |
| authorization: str = Header(None) | |
| ): | |
| verify_api_key(authorization) | |
| messages = [ | |
| m.model_dump() | |
| for m in req.messages | |
| ] | |
| # ========================= | |
| # STREAM | |
| # ========================= | |
| if req.stream: | |
| return StreamingResponse( | |
| stream_generate( | |
| req.model, | |
| messages | |
| ), | |
| media_type="text/event-stream" | |
| ) | |
| # ========================= | |
| # NORMAL | |
| # ========================= | |
| loop = asyncio.get_event_loop() | |
| response = await loop.run_in_executor( | |
| executor, | |
| lambda: generate( | |
| req.model, | |
| messages | |
| ) | |
| ) | |
| return { | |
| "choices": [ | |
| { | |
| "message": { | |
| "role": "assistant", | |
| "content": response | |
| } | |
| } | |
| ] | |
| } |