"""FastAPI application for the Spreadsheet Environment.""" from __future__ import annotations import os import sys from pathlib import Path from dotenv import load_dotenv from fastapi.middleware.cors import CORSMiddleware try: from openenv.core.env_server.http_server import create_app except ImportError as e: raise ImportError( "openenv is required. Install with: uv sync" ) from e load_dotenv(os.path.join(os.path.dirname(__file__), "..", ".env")) import openenv.core.env_server.web_interface as _wi # noqa: E402 _wi.DEFAULT_QUICK_START_MARKDOWN = """ ### How to use this environment **Spreadsheet** — exact workbook manipulation and reasoning over realistic spreadsheet tasks. Read sheets, understand structure, write values/formulas, and submit for automated evaluation. Use the **Playground** on the right. Type a **Tool Name** and **Arguments Json**, then click **Step**. --- #### 1. Start a session 1. Click **Reset** 2. `list_tools` → `{}` — discover all 13 tools & their params 3. `list_scenarios` → `{}` — see all 12 scenarios 4. `load_scenario` → `{"scenario_id": "formula_repair_01"}` #### 2. Explore the workbook - `list_sheets` → `{}` — sheet names, dimensions, visibility - `read_range` → `{"sheet": "Summary", "range": "A1:F10"}` — read cells - `inspect_formula` → `{"sheet": "Summary", "cell": "C5"}` — raw formula string - `list_named_targets` → `{}` — allowed output zones - `get_session_info` → `{}` — session metadata, step count - `get_edit_history` → `{}` — all edits so far > **Note:** `read_range` uses **A1 notation** (e.g. `"B2:D10"`). Formulas are returned as strings. #### 3. Edit cells - `write_cell` → `{"sheet": "Summary", "cell": "C5", "value": "=SUM(B2:B10)"}` — write one cell - `write_range` → `{"sheet": "Summary", "start_cell": "A1", "data": "[[1, 2], [3, 4]]"}` — write a block > **Note:** `write_range` uses **start_cell** (not `cell`). The `data` arg is a JSON string of a 2D array. > Values starting with `=` are treated as formulas. Numeric strings are auto-converted. #### 4. Validate & submit - `validate_partial` → `{}` — check progress (pass/fail count, no answers revealed) - `submit_workbook` → `{}` — final evaluation (pass rate + per-check results) - `reset_scenario` → `{}` — restore workbook to original (scenario stays loaded) > Use `validate_partial` before `submit_workbook` to gauge progress without ending the task. --- #### Scenarios (12) `formula_repair_01` · `formula_repair_02` · `cross_sheet_lookup_01` · `cross_sheet_lookup_02` · `conditional_aggregation_01` · `conditional_aggregation_02` · `ledger_reconciliation_01` · `ledger_reconciliation_02` · `messy_table_extraction_01` · `range_transformation_01` · `schedule_grid_fill_01` · `buggy_template_fix_01` #### Connect from Python ```python from spreadsheet import SpreadsheetAction, SpreadsheetEnv env = SpreadsheetEnv(base_url="http://localhost:8000") obs = env.reset() obs = await env.step(SpreadsheetAction( tool_name="load_scenario", arguments_json='{"scenario_id": "formula_repair_01"}' )) ``` For more, see the [OpenEnv documentation](https://meta-pytorch.org/OpenEnv/). """ try: from spreadsheet.models import SpreadsheetAction, SpreadsheetObservation from spreadsheet.server.spreadsheet_environment import SpreadsheetEnvironment except ImportError: sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from models import SpreadsheetAction, SpreadsheetObservation from server.spreadsheet_environment import SpreadsheetEnvironment MAX_CONCURRENT_ENVS = int(os.getenv("MAX_CONCURRENT_ENVS", "8")) app = create_app( SpreadsheetEnvironment, SpreadsheetAction, SpreadsheetObservation, env_name="spreadsheet", max_concurrent_envs=MAX_CONCURRENT_ENVS, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) def main(host: str = "0.0.0.0", port: int = 8000): import uvicorn uvicorn.run(app, host=host, port=port) if __name__ == "__main__": main()