jostlebot's picture
Use anthropic_key secret name
f33abb4
"""
Tolerate Space Lab - Backend
A therapeutic intervention tool for building distress tolerance
"""
import os
import httpx
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from pydantic import BaseModel
from typing import List
app = FastAPI()
# Get API key from environment (set as HF Space secret)
ANTHROPIC_API_KEY = os.environ.get("anthropic_key", "")
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
messages: List[Message]
system: str
max_tokens: int = 300
class AnalysisRequest(BaseModel):
prompt: str
max_tokens: int = 1000
@app.post("/api/chat")
async def chat(request: ChatRequest):
"""Proxy chat requests to Claude API"""
if not ANTHROPIC_API_KEY:
raise HTTPException(status_code=500, detail="API key not configured")
async with httpx.AsyncClient() as client:
try:
response = await client.post(
"https://api.anthropic.com/v1/messages",
headers={
"Content-Type": "application/json",
"x-api-key": ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01"
},
json={
"model": "claude-sonnet-4-20250514",
"max_tokens": request.max_tokens,
"system": request.system,
"messages": [{"role": m.role, "content": m.content} for m in request.messages]
},
timeout=60.0
)
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/api/analysis")
async def analysis(request: AnalysisRequest):
"""Proxy analysis requests to Claude API"""
if not ANTHROPIC_API_KEY:
raise HTTPException(status_code=500, detail="API key not configured")
async with httpx.AsyncClient() as client:
try:
response = await client.post(
"https://api.anthropic.com/v1/messages",
headers={
"Content-Type": "application/json",
"x-api-key": ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01"
},
json={
"model": "claude-sonnet-4-20250514",
"max_tokens": request.max_tokens,
"messages": [{"role": "user", "content": request.prompt}]
},
timeout=60.0
)
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Serve static files
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/")
async def root():
return FileResponse("static/index.html")