Spaces:
Sleeping
Sleeping
File size: 5,816 Bytes
c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab 7b5cf62 ee933ab c532e4a ee933ab c532e4a e7d4d61 ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab e7d4d61 ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab c532e4a ee933ab | 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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | """FastAPI application for the FlakeForge environment server.
Mounts:
- OpenEnv core routes (/reset, /step) for RL training compatibility
- FlakeForge API (/api/*) for the web UI and external integrations
- Static homepage (GET /)
- CORS middleware for frontend development
"""
import sys
import os
import logging
from pathlib import Path
project_root = str(Path(__file__).parents[1])
if project_root not in sys.path:
sys.path.insert(0, project_root)
# Local dev: load repo `.env` so HUGGING_FACE_TOKEN / HF_TOKEN are available to the API and challenge LLM.
try:
from dotenv import load_dotenv
load_dotenv(Path(project_root) / ".env", override=False)
except ImportError:
pass
try:
from openenv.core.env_server.http_server import create_app
except Exception as e:
raise ImportError(
"openenv is required for the web interface. Install dependencies with '\n uv sync\n'"
) from e
try:
from ..models import FlakeForgeAction, FlakeForgeObservation
from .FlakeForge_environment import FlakeForgeEnvironment
except ImportError:
try:
from FlakeForge.models import FlakeForgeAction, FlakeForgeObservation
from FlakeForge.server.FlakeForge_environment import FlakeForgeEnvironment
except ImportError:
from models import FlakeForgeAction, FlakeForgeObservation # type: ignore
from server.FlakeForge_environment import FlakeForgeEnvironment # type: ignore
from fastapi.middleware.cors import CORSMiddleware
from fastapi import HTTPException
from fastapi.responses import HTMLResponse
from fastapi.routing import APIRoute
logger = logging.getLogger("flakeforge")
# ββ Create the base OpenEnv app βββββββββββββββββββββββββββββββββββββββββββββ
app = create_app(FlakeForgeEnvironment, FlakeForgeAction, FlakeForgeObservation)
# Ensure our custom homepage wins over OpenEnv's default playground at "/".
app.router.routes = [
route
for route in app.router.routes
if not (
isinstance(route, APIRoute)
and route.path == "/"
and "GET" in route.methods
)
]
# ββ CORS βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ββ Mount the FlakeForge API router βββββββββββββββββββββββββββββββββββββββββ
try:
from .api import router as api_router
except ImportError:
try:
from server.api import router as api_router
except ImportError:
from FlakeForge.server.api import router as api_router # type: ignore
app.include_router(api_router)
# ββ Homepage βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
@app.get("/", response_class=HTMLResponse)
def homepage():
"""Serve the FlakeForge marketing / demo UI (Hugging Face App tab at `/`)."""
html_path = Path(__file__).resolve().parents[1] / "templates" / "index.html"
if not html_path.is_file():
raise HTTPException(
status_code=500,
detail=f"Missing UI template: {html_path.as_posix()}",
)
return html_path.read_text(encoding="utf-8")
# ββ Startup / shutdown events ββββββββββββββββββββββββββββββββββββββββββββββββ
@app.on_event("startup")
async def on_startup():
logger.info("FlakeForge server starting...")
logger.info(" Project root: %s", project_root)
logger.info(" API docs: http://localhost:8000/docs")
logger.info(" Homepage: http://localhost:8000/")
logger.info(" Health check: http://localhost:8000/api/health")
@app.on_event("shutdown")
async def on_shutdown():
logger.info("FlakeForge server shutting down.")
# ββ CLI entry point ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def main(host: str = "0.0.0.0", port: int = 8000):
"""Entry point for direct execution.
Usage:
uv run --project . server
uv run --project . server --port 8001
python -m FlakeForge.server.app
"""
import argparse
import uvicorn
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
)
parser = argparse.ArgumentParser(description="FlakeForge Environment Server")
parser.add_argument("--host", type=str, default=host, help="Host address")
parser.add_argument("--port", type=int, default=port, help="Port number")
parser.add_argument("--reload", action="store_true", help="Auto-reload on code changes")
parser.add_argument("--workers", type=int, default=1, help="Number of workers")
args, _ = parser.parse_known_args()
logger.info("Starting FlakeForge server on %s:%d", args.host, args.port)
uvicorn.run(
"server.app:app" if args.reload else app,
host=args.host,
port=args.port,
reload=args.reload,
workers=args.workers,
log_level="info",
)
if __name__ == "__main__":
main()
|