Spaces:
Sleeping
Sleeping
from fastapi import FastAPI, HTTPException, Depends, Header, Request | |
from fastapi.responses import StreamingResponse | |
from pydantic import BaseModel | |
from typing import List, Optional, Literal | |
import json | |
import g4f | |
from g4f.Provider import OpenaiAccount, RetryProvider | |
from g4f.models import ModelUtils | |
app = FastAPI() | |
# Complete list of available models from G4F | |
models = [ | |
# OpenAI models | |
"gpt-4", "gpt-4-turbo", "gpt-4o", "gpt-3.5-turbo", | |
# Anthropic models | |
"claude-3-opus", "claude-3-sonnet", "claude-3-haiku", "claude-2.1", | |
# Google models | |
"gemini-pro", "gemini-1.5-pro", "gemini-1.5-flash", | |
# Meta models | |
"llama-2-70b", "llama-2-13b", "llama-2-7b", "llama-3-70b", "llama-3-8b", | |
# Other providers | |
"mistral-7b", "mixtral-8x7b", "command-r-plus", "cohere-command-r", | |
"deepseek-chat", "deepseek-coder", "code-llama-34b", "code-llama-70b", | |
# Specialized models | |
"grok-1", "grok-1.5", "grok-2", "o1", "o3-mini", "flux", "flux-pro" | |
] | |
# Configure G4F backend | |
class CustomBackend(g4f.Provider.BackendApi): | |
working = True | |
ssl = False | |
url = "https://ahe.hopto.org" | |
headers = {"Authorization": "Basic Z2dnOmc0Zl8="} | |
async def create_async_generator( | |
cls, | |
model: str, | |
messages: g4f.typing.Messages, | |
**kwargs | |
) -> g4f.typing.AsyncResult: | |
if model in OpenaiAccount.get_models(): | |
kwargs["provider"] = OpenaiAccount | |
async for chunk in super().create_async_generator(model, messages, **kwargs): | |
yield chunk | |
# Pydantic models | |
class Message(BaseModel): | |
role: Literal["system", "user", "assistant"] | |
content: str | |
class ChatRequest(BaseModel): | |
model: str | |
messages: List[Message] | |
temperature: Optional[float] = 0.7 | |
max_tokens: Optional[int] = None | |
top_p: Optional[float] = 0.9 | |
streaming: bool = True | |
class ChatResponse(BaseModel): | |
role: str = "assistant" | |
content: str | |
model: Optional[str] = None | |
class ModelListResponse(BaseModel): | |
models: List[str] | |
# API Key Verification | |
async def verify_api_key(x_api_key: str = Header(...)): | |
if x_api_key != "fb207532285886a5568298b4b4e61124": | |
raise HTTPException(status_code=403, detail="Invalid API key") | |
async def get_models(): | |
"""Get list of all available models""" | |
return ModelListResponse(models=models) | |
async def chat_completion( | |
request: ChatRequest, | |
api_key: str = Depends(verify_api_key) | |
): | |
""" | |
Handle chat completion requests with streaming support. | |
Args: | |
request: ChatRequest containing model, messages and parameters | |
api_key: Verified API key | |
Returns: | |
Either a StreamingResponse or direct ChatResponse | |
""" | |
# Validate model | |
if request.model not in models: | |
raise HTTPException( | |
status_code=400, | |
detail=f"Invalid model. Available models: {', '.join(models)}" | |
) | |
# Prepare messages | |
messages = [{"role": msg.role, "content": msg.content} for msg in request.messages] | |
try: | |
if request.streaming: | |
async def stream_generator(): | |
response = await g4f.ChatCompletion.create_async( | |
model=request.model, | |
messages=messages, | |
temperature=request.temperature, | |
top_p=request.top_p, | |
max_tokens=request.max_tokens, | |
provider=RetryProvider([CustomBackend]) | |
) | |
async for chunk in response: | |
if isinstance(chunk, dict): | |
yield f"data: {json.dumps(chunk)}\n\n" | |
else: | |
yield f"data: {json.dumps({'content': str(chunk)})}\n\n" | |
yield "data: [DONE]\n\n" | |
return StreamingResponse( | |
stream_generator(), | |
media_type="text/event-stream" | |
) | |
else: | |
response = await g4f.ChatCompletion.create_async( | |
model=request.model, | |
messages=messages, | |
temperature=request.temperature, | |
top_p=request.top_p, | |
max_tokens=request.max_tokens, | |
provider=RetryProvider([CustomBackend]) | |
) | |
if isinstance(response, str): | |
return ChatResponse(content=response, model=request.model) | |
elif isinstance(response, dict): | |
return ChatResponse( | |
content=response.get("choices", [{}])[0].get("message", {}).get("content", ""), | |
model=request.model | |
) | |
return ChatResponse(content=str(response), model=request.model | |
except Exception as e: | |
raise HTTPException( | |
status_code=500, | |
detail=f"Error processing request: {str(e)}" | |
) | |
if __name__ == "__main__": | |
import uvicorn | |
uvicorn.run(app, host="0.0.0.0", port=7860) |