Spaces:
Sleeping
Sleeping
feat: implement FastAPI backend and frontend proxy configuration for brain management services
37f2357 | import os | |
| import sys | |
| from pathlib import Path | |
| from typing import List, Optional | |
| from fastapi import FastAPI, HTTPException, Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import FileResponse | |
| from pydantic import BaseModel | |
| # Add parent directory to sys.path to allow importing the brain package | |
| sys.path.append(str(Path(__file__).resolve().parents[2])) | |
| from brain.paths import get_brains_dir, get_brain_path | |
| from brain.config import load_config, save_config | |
| from brain.templates.brain_instance import scaffold_brain_instance | |
| app = FastAPI(title="Ever Brain API") | |
| # Configure CORS | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], # In production, specify the actual frontend URL | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| class BrainCreateRequest(BaseModel): | |
| name: str | |
| class BrainUseRequest(BaseModel): | |
| name: str | |
| class BrainStatusResponse(BaseModel): | |
| active_brain: Optional[str] | |
| brains_path: str | |
| brain_count: int | |
| async def get_status(): | |
| config = load_config() | |
| brains_dir = get_brains_dir() | |
| brains = [d.name for d in brains_dir.iterdir() if d.is_dir()] | |
| active_path_str = config.get("active_brain") | |
| active_brain_name = Path(active_path_str).name if active_path_str else None | |
| return { | |
| "active_brain": active_brain_name, | |
| "brains_path": str(brains_dir), | |
| "brain_count": len(brains) | |
| } | |
| async def list_brains(): | |
| brains_dir = get_brains_dir() | |
| return [d.name for d in brains_dir.iterdir() if d.is_dir()] | |
| async def create_brain(request: BrainCreateRequest): | |
| brain_path = get_brain_path(request.name) | |
| if brain_path.exists(): | |
| raise HTTPException(status_code=400, detail=f"Brain instance '{request.name}' already exists.") | |
| try: | |
| scaffold_brain_instance(brain_path) | |
| return {"message": f"Brain '{request.name}' created successfully.", "path": str(brain_path)} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def use_brain(request: BrainUseRequest): | |
| brain_path = get_brain_path(request.name) | |
| if not brain_path.exists(): | |
| raise HTTPException(status_code=404, detail=f"Brain instance '{request.name}' not found.") | |
| from brain.config import set_active_brain | |
| set_active_brain(brain_path) | |
| return {"message": f"Active brain set to '{request.name}'."} | |
| async def download_cli(): | |
| # Path to the pre-packaged binary | |
| binary_path = Path(__file__).resolve().parents[2] / "dist" / "ever-brain.exe" | |
| if not binary_path.exists(): | |
| raise HTTPException(status_code=404, detail="CLI binary not found. Please run the packaging script.") | |
| return FileResponse( | |
| path=binary_path, | |
| filename="ever-brain.exe", | |
| media_type="application/octet-stream" | |
| ) | |
| async def download_setup(): | |
| # Path to the GUI installer | |
| setup_path = Path(__file__).resolve().parents[2] / "dist" / "EverBrainSetup.exe" | |
| if not setup_path.exists(): | |
| raise HTTPException(status_code=404, detail="GUI Setup installer not found. Please compile the .iss script.") | |
| return FileResponse( | |
| path=setup_path, | |
| filename="EverBrainSetup.exe", | |
| media_type="application/octet-stream" | |
| ) | |
| async def download_install_script(request: Request): | |
| # Path to the web installation script | |
| script_path = Path(__file__).resolve().parents[2] / "scripts" / "web_install.ps1" | |
| if not script_path.exists(): | |
| raise HTTPException(status_code=404, detail="Installation script not found.") | |
| # Read script and inject the current host URL | |
| content = script_path.read_text(encoding="utf-8") | |
| # Hugging Face usually has 'x-forwarded-proto' and 'host' headers | |
| protocol = request.headers.get("x-forwarded-proto", "http") | |
| host = request.headers.get("host", "localhost:8000") | |
| base_url = f"{protocol}://{host}" | |
| content = content.replace('http://localhost:8000', base_url) | |
| from fastapi.responses import Response | |
| return Response( | |
| content=content, | |
| media_type="text/plain", | |
| headers={"Content-Disposition": "attachment; filename=install.ps1"} | |
| ) | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=8000) | |