Spaces:
Sleeping
Sleeping
File size: 3,757 Bytes
fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 82bb4d1 fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e fdcb6c5 ea4b76e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | import os
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Literal
import httpx
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Read API keys from Hugging Face Secrets
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
HF_TOKEN = os.environ.get("HF_TOKEN")
if not OPENAI_API_KEY:
logger.warning("OPENAI_API_KEY not set — OpenAI provider will be unavailable")
if not HF_TOKEN:
logger.warning("HF_TOKEN not set — Hugging Face provider will be unavailable")
# Provider config: each provider has a base URL and a key
PROVIDERS = {
"openai": {
"url": "https://api.openai.com/v1/chat/completions",
"key": OPENAI_API_KEY,
},
"hf": {
"url": "https://router.huggingface.co/v1/chat/completions",
"key": HF_TOKEN,
},
}
app = FastAPI(title="Proxy for Unity")
# Enable CORS for Unity WebGL builds
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # In production, specify your domain
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
model: str
temperature: float
messages: List[Message]
provider: Literal["openai", "hf"] = "openai" # default keeps existing Unity code working
@app.get("/")
async def root():
return {
"status": "running",
"message": "Proxy Active",
"providers": {
"openai": bool(OPENAI_API_KEY),
"hf": bool(HF_TOKEN),
},
"endpoints": {
"chat": "POST /chat"
}
}
@app.post("/chat")
async def proxy_chat(request: ChatRequest):
provider_config = PROVIDERS.get(request.provider)
if not provider_config or not provider_config["key"]:
raise HTTPException(
status_code=400,
detail=f"Provider '{request.provider}' is not configured"
)
try:
logger.info(
f"Provider: {request.provider} | Model: {request.model} | "
f"Messages: {len(request.messages)}"
)
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(
provider_config["url"],
json={
"model": request.model,
"temperature": request.temperature,
"messages": [
{"role": msg.role, "content": msg.content}
for msg in request.messages
]
},
headers={
"Authorization": f"Bearer {provider_config['key']}",
"Content-Type": "application/json"
}
)
if response.status_code != 200:
logger.error(f"{request.provider} API error: {response.text}")
raise HTTPException(
status_code=response.status_code,
detail=response.text
)
result = response.json()
logger.info(f"Successfully proxied {request.provider} request")
return result
except httpx.HTTPError as e:
logger.error(f"HTTP error: {str(e)}")
raise HTTPException(status_code=500, detail=f"Proxy error: {str(e)}")
except Exception as e:
logger.error(f"Unexpected error: {str(e)}")
raise HTTPException(status_code=500, detail=f"Server error: {str(e)}")
@app.get("/health")
async def health():
return {
"status": "healthy",
"openai_configured": bool(OPENAI_API_KEY),
"hf_configured": bool(HF_TOKEN),
}
|