"""FastAPI application for the Startup Survival Simulator."""
from fastapi import FastAPI, HTTPException
from fastapi.responses import HTMLResponse
from baseline import run_baseline
from env import StartupEnv
from grader import grade
from models import ResetRequest, StepRequest
from tasks import get_tasks
app = FastAPI(
title="Startup Survival Simulator",
description="OpenEnv-style startup decision environment for hackathon evaluation.",
version="1.0.0",
)
# Keep a single in-process environment instance for the simple demo API.
env = StartupEnv(seed=42)
@app.get("/", response_class=HTMLResponse)
def root() -> str:
"""Human-friendly landing page that also guarantees an HTTP 200 at the Space root."""
return """
Startup Survival Simulator
Startup Survival Simulator
An OpenEnv-style startup management environment where an AI agent learns to balance
growth, burn, churn, morale, and revenue through a standard reset() /
step() / state() interface.
This deployment is judge-friendly out of the box: no setup, no secrets, and all core
evaluation endpoints are live.
Quick Start
- Send
POST /reset to start a fresh episode.
- Send
POST /step with an action like increase_marketing.
- Use
GET /grader?task_name=survival to score the current run.
"""
@app.post("/reset")
def reset_environment(request: ResetRequest | None = None) -> dict:
"""Reset the environment and return the initial state."""
seed = request.seed if request else None
return env.reset(seed=seed).model_dump()
@app.post("/step")
def step_environment(request: StepRequest) -> dict:
"""Execute one environment step."""
try:
return env.step(request.action.value)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.get("/state")
def get_state() -> dict:
"""Return the current state."""
return env.state().model_dump()
@app.get("/tasks")
def list_tasks() -> dict:
"""Return task metadata and action schema."""
return get_tasks()
@app.get("/grader")
def run_grader(task_name: str) -> dict:
"""Grade the current environment state for a task."""
try:
return grade(task_name, env.state().model_dump())
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@app.get("/baseline")
def execute_baseline(seed: int = 42) -> dict:
"""Run the deterministic baseline policy for all tasks."""
return run_baseline(seed=seed)