""" 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")