Spaces:
Sleeping
Sleeping
Download server/app.py from Nitesh321/sql-analytics-env: direct link, hf CLI and curl.
- Browser
- Download file 4.58 kB
-
https://huggingface.co/spaces/Nitesh321/sql-analytics-env/resolve/main/server/app.py
- Command line
-
hf download hf://spaces/Nitesh321/sql-analytics-env/server/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Nitesh321/sql-analytics-env/resolve/main/server/app.py
4.58 kB
| """ | |
| server/app.py | |
| ------------- | |
| FastAPI application for the SQL Analytics Environment. | |
| Exposes the environment over HTTP + WebSocket endpoints that are | |
| consumed by EnvClient / the OpenEnv evaluation harness. | |
| Usage (development): | |
| uvicorn server.app:app --reload --host 0.0.0.0 --port 8000 | |
| Usage (production via Docker): | |
| uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 1 | |
| """ | |
| import time | |
| from fastapi import Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| try: | |
| from openenv.core.env_server.http_server import create_app | |
| from .sql_analytics_environment import SQLAnalyticsEnvironment | |
| from ..models import SQLAction, SQLObservation | |
| except ImportError: | |
| from openenv.core.env_server.http_server import create_app | |
| from server.sql_analytics_environment import SQLAnalyticsEnvironment | |
| from models import SQLAction, SQLObservation | |
| # ββ Create base app βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Pass the class (not an instance) so the HTTP server can instantiate | |
| # a fresh environment per WebSocket session. | |
| app = create_app( | |
| SQLAnalyticsEnvironment, | |
| SQLAction, | |
| SQLObservation, | |
| env_name="sql_analytics_env", | |
| ) | |
| # ββ CORS β allow all origins (needed for HuggingFace Spaces) βββββββββββββββββ | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ββ Explicit health check (required by OpenEnv validator + hackathon) βββββββββ | |
| async def health(): | |
| """ | |
| Health check endpoint. | |
| Returns HTTP 200 when the server is up and ready. | |
| Required by OpenEnv pre-submission checks. | |
| """ | |
| return {"status": "ok", "environment": "sql_analytics_env", "version": "0.1.0"} | |
| # ββ Environment metadata ββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def info(): | |
| """Return environment metadata for discoverability.""" | |
| return { | |
| "name": "sql_analytics_env", | |
| "version": "0.1.0", | |
| "description": ( | |
| "SQL Analytics environment where AI agents answer " | |
| "business-intelligence questions by writing SQL queries " | |
| "against a seeded e-commerce database." | |
| ), | |
| "tasks": [ | |
| {"task_id": "task_001", "difficulty": "easy", "topic": "Count customers by state"}, | |
| {"task_id": "task_002", "difficulty": "easy", "topic": "Most expensive product in category"}, | |
| {"task_id": "task_003", "difficulty": "medium", "topic": "Top 5 customers by spend"}, | |
| {"task_id": "task_004", "difficulty": "medium", "topic": "Category with highest avg rating"}, | |
| {"task_id": "task_005", "difficulty": "hard", "topic": "Q1-only buyers (churn signal)"}, | |
| {"task_id": "task_006", "difficulty": "hard", "topic": "Monthly revenue + growth rate"}, | |
| ], | |
| "action_space": "SQLAction { sql: str }", | |
| "observation_space": "SQLObservation { result, error, db_schema, task_description, reward, done }", | |
| "reward_range": [0.0, 1.0], | |
| "max_steps": 10, | |
| } | |
| # ββ Request timing middleware (helps with debugging slow queries) βββββββββββββ | |
| async def add_process_time_header(request: Request, call_next): | |
| start = time.perf_counter() | |
| response = await call_next(request) | |
| elapsed = round(time.perf_counter() - start, 4) | |
| response.headers["X-Process-Time"] = str(elapsed) | |
| return response | |
| # ββ Global exception handler ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def global_exception_handler(request: Request, exc: Exception): | |
| return JSONResponse( | |
| status_code=500, | |
| content={ | |
| "error": type(exc).__name__, | |
| "detail": str(exc), | |
| "path": str(request.url), | |
| }, | |
| ) | |
| def main() -> None: | |
| """Entry point for direct execution.""" | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=8000) | |
| if __name__ == "__main__": | |
| main() | |