Deadman922 commited on
Commit
9bdab6c
·
verified ·
1 Parent(s): d5b7516

Delete server/main.py

Browse files
Files changed (1) hide show
  1. server/main.py +0 -217
server/main.py DELETED
@@ -1,217 +0,0 @@
1
- import asyncio
2
-
3
- from fastapi import FastAPI, HTTPException
4
- from fastapi.responses import HTMLResponse
5
-
6
- from server.environment import SQLQualityEnvironment
7
- from server.models import (
8
- HealthResponse,
9
- ResetRequest,
10
- SQLAction,
11
- SQLObservation,
12
- SQLState,
13
- StepResponse,
14
- )
15
-
16
- app = FastAPI(
17
- title="SQL Quality Audit Agent Environment",
18
- description="OpenEnv-compatible environment for training AI agents on SQL data quality tasks",
19
- version="0.1.0",
20
- )
21
-
22
- # Module-level singleton — ONE instance shared across all requests
23
- _env = SQLQualityEnvironment()
24
-
25
- # HTTP-level request lock to serialize concurrent requests
26
- _request_lock = asyncio.Lock()
27
-
28
-
29
- @app.get("/", response_class=HTMLResponse)
30
- async def root():
31
- """Root endpoint for HF Space App section - provides testing interface."""
32
- return """
33
- <!DOCTYPE html>
34
- <html>
35
- <head>
36
- <title>SQL Quality Environment</title>
37
- <style>
38
- body { font-family: system-ui, sans-serif; max-width: 800px; margin: 40px auto; padding: 20px; }
39
- h1 { color: #2563eb; }
40
- .endpoint { background: #f3f4f6; padding: 15px; margin: 10px 0; border-radius: 8px; }
41
- .method { font-weight: bold; color: #059669; }
42
- code { background: #e5e7eb; padding: 2px 6px; border-radius: 4px; }
43
- button { background: #2563eb; color: white; border: none; padding: 10px 20px;
44
- border-radius: 6px; cursor: pointer; margin: 5px; }
45
- button:hover { background: #1d4ed8; }
46
- #result { background: #1f2937; color: #10b981; padding: 15px; border-radius: 8px;
47
- margin-top: 20px; font-family: monospace; white-space: pre-wrap; display: none; }
48
- </style>
49
- </head>
50
- <body>
51
- <h1>📊 SQL Quality Audit Agent Environment</h1>
52
- <p>OpenEnv-compatible environment for training AI agents on SQL data quality tasks.</p>
53
-
54
- <h2>Available Endpoints</h2>
55
- <div class="endpoint">
56
- <span class="method">GET</span> <code>/health</code> - Health check
57
- </div>
58
- <div class="endpoint">
59
- <span class="method">POST</span> <code>/ping</code> - Ping for validator
60
- </div>
61
- <div class="endpoint">
62
- <span class="method">POST</span> <code>/reset</code> - Reset environment (requires task_id)
63
- </div>
64
- <div class="endpoint">
65
- <span class="method">POST</span> <code>/step</code> - Execute action
66
- </div>
67
- <div class="endpoint">
68
- <span class="method">GET</span> <code>/state</code> - Get current state
69
- </div>
70
-
71
- <h2>Quick Test</h2>
72
- <button onclick="testHealth()">Test /health</button>
73
- <button onclick="testReset()">Test /reset (null_audit)</button>
74
-
75
- <div id="result"></div>
76
-
77
- <script>
78
- async function testHealth() {
79
- const res = await fetch('/health');
80
- const data = await res.json();
81
- showResult('GET /health\\nStatus: ' + res.status + '\\nResponse: ' + JSON.stringify(data, null, 2));
82
- }
83
-
84
- async function testReset() {
85
- const res = await fetch('/reset', {
86
- method: 'POST',
87
- headers: {'Content-Type': 'application/json'},
88
- body: JSON.stringify({task_id: 'null_audit', seed: 42})
89
- });
90
- const data = await res.json();
91
- showResult('POST /reset\\nStatus: ' + res.status + '\\nResponse: ' + JSON.stringify(data, null, 2).slice(0, 500) + '...');
92
- }
93
-
94
- function showResult(text) {
95
- const el = document.getElementById('result');
96
- el.textContent = text;
97
- el.style.display = 'block';
98
- }
99
- </script>
100
- </body>
101
- </html>
102
- """
103
-
104
-
105
- @app.get("/health", response_model=HealthResponse)
106
- async def health() -> HealthResponse:
107
- """Health check endpoint for HF Space ping validation.
108
-
109
- Returns:
110
- dict: Status response indicating the server is running
111
- """
112
- return HealthResponse(status="ok")
113
-
114
-
115
- @app.post("/ping", response_model=HealthResponse)
116
- async def ping() -> HealthResponse:
117
- """Ping endpoint for submission validator — accepts empty body.
118
-
119
- Returns:
120
- dict: Status response indicating the server is responsive
121
- """
122
- return HealthResponse(status="ok")
123
-
124
-
125
- @app.post("/reset", response_model=SQLObservation)
126
- async def reset(request: ResetRequest) -> SQLObservation:
127
- """Reset environment and return initial observation for specified task.
128
-
129
- Args:
130
- request: ResetRequest containing task_id and optional deterministic seed
131
-
132
- Returns:
133
- SQLObservation: Initial state of database for requested task
134
-
135
- Raises:
136
- HTTPException 422: If task_id is not a valid task identifier
137
- HTTPException 500: If environment initialization fails
138
- """
139
- async with _request_lock:
140
- VALID_TASKS = {
141
- "null_audit",
142
- "type_repair",
143
- "dedup_bug",
144
- "fk_integrity",
145
- "schema_drift",
146
- }
147
- if request.task_id not in VALID_TASKS:
148
- raise HTTPException(
149
- status_code=422,
150
- detail=f"Invalid task_id '{request.task_id}'. Must be one of: {VALID_TASKS}",
151
- )
152
- try:
153
- return _env.reset(request.task_id, seed=request.seed)
154
- except Exception as e:
155
- raise HTTPException(status_code=500, detail=str(e))
156
-
157
-
158
- @app.post("/step", response_model=StepResponse)
159
- async def step(action: SQLAction) -> StepResponse:
160
- """Submit an action and receive observation, reward, done flag, and info.
161
-
162
- Args:
163
- action: SQLAction containing task_id and fix_query or answer
164
-
165
- Returns:
166
- StepResponse: Updated observation, reward, done status, and info
167
-
168
- Raises:
169
- HTTPException 422: If action is invalid or episode is already done
170
- HTTPException 500: If environment step execution fails
171
- """
172
- async with _request_lock:
173
- try:
174
- return _env.step(action)
175
- except HTTPException:
176
- raise
177
- except ValueError as e:
178
- raise HTTPException(status_code=422, detail=str(e))
179
- except Exception as e:
180
- raise HTTPException(status_code=500, detail=str(e))
181
-
182
-
183
- @app.get("/state", response_model=SQLState)
184
- async def state() -> SQLState:
185
- """Get current episode state.
186
-
187
- Returns:
188
- SQLState: Current episode information including task_id, episode_id, attempt_number, cumulative_reward, and done status
189
-
190
- Raises:
191
- HTTPException 422: If no active episode exists
192
- """
193
- try:
194
- return _env.state()
195
- except ValueError as e:
196
- raise HTTPException(status_code=422, detail=str(e))
197
-
198
-
199
- def run_server() -> None:
200
- """
201
- Entry point for 'uv run server' command.
202
-
203
- Uses PORT environment variable if set, otherwise defaults to 7860
204
- (matching the Dockerfile EXPOSE and HF Spaces convention).
205
- Override locally: PORT=8000 uv run server
206
- """
207
- import os
208
-
209
- import uvicorn
210
-
211
- port = int(os.getenv("PORT", "7860"))
212
- uvicorn.run("server.main:app", host="0.0.0.0", port=port, reload=False)
213
-
214
-
215
- def main() -> None:
216
- """Primary CLI entrypoint expected by OpenEnv validators."""
217
- run_server()