Skip to content

Commit ee331ac

Browse files
authored
api to fetch ai generated submisson tiem series (#156)
* hidemetadata * hidemetadata
1 parent 7b1b1a0 commit ee331ac

File tree

1 file changed

+124
-2
lines changed

1 file changed

+124
-2
lines changed

kernelboard/api/leaderboard.py

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any
1+
import re
2+
from typing import Any, List
23
from flask import Blueprint
34
from kernelboard.lib.db import get_db_connection
45
from kernelboard.lib.time import to_time_left
@@ -9,7 +10,9 @@
910

1011
logger = logging.getLogger(__name__)
1112

12-
leaderboard_bp = Blueprint("leaderboard_bp", __name__, url_prefix="/leaderboard")
13+
leaderboard_bp = Blueprint(
14+
"leaderboard_bp", __name__, url_prefix="/leaderboard"
15+
)
1316

1417

1518
@leaderboard_bp.route("/<int:leaderboard_id>", methods=["GET"])
@@ -188,3 +191,122 @@ def is_result_invalid(result):
188191
return True
189192

190193
return False
194+
195+
196+
# ai generated code hardcoded user_id
197+
HARDCODED_USER_ID = "205851652572315658"
198+
199+
200+
@leaderboard_bp.route("/ai_trend/<int:leaderboard_id>", methods=["GET"])
201+
def get_ai_trend(leaderboard_id: int):
202+
"""
203+
GET /leaderboard/timeseries/<leaderboard_id>
204+
205+
Returns time series data for submissions matching file name patterns like:
206+
- H100_claude-opus-4.5_ka_submission
207+
- H100_gpt-5-2_ka_submission
208+
- H100_gpt-5_ka_submission
209+
"""
210+
total_start = time.perf_counter()
211+
212+
conn = get_db_connection()
213+
query_start = time.perf_counter()
214+
215+
with conn.cursor() as cur:
216+
sql = """
217+
SELECT
218+
s.id AS submission_id,
219+
s.file_name,
220+
s.submission_time,
221+
r.score,
222+
r.passed,
223+
r.runner AS gpu_type,
224+
r.mode
225+
FROM leaderboard.submission s
226+
JOIN leaderboard.runs r ON r.submission_id = s.id
227+
WHERE s.user_id = %s
228+
AND s.leaderboard_id = %s
229+
AND r.score IS NOT NULL
230+
AND r.passed = true
231+
AND NOT r.secret
232+
ORDER BY s.submission_time ASC
233+
"""
234+
cur.execute(sql, (HARDCODED_USER_ID, leaderboard_id))
235+
rows = cur.fetchall()
236+
237+
query_time = (time.perf_counter() - query_start) * 1000
238+
239+
if not rows:
240+
return http_success(data={
241+
"leaderboard_id": leaderboard_id,
242+
"time_series": {},
243+
})
244+
245+
items = []
246+
for row in rows:
247+
(submission_id, file_name, submission_time,
248+
score, passed, gpu_type, mode) = row
249+
model_name = parse_model_from_filename(file_name)
250+
251+
items.append({
252+
"submission_id": submission_id,
253+
"file_name": file_name,
254+
"submission_time": (
255+
submission_time.isoformat() if submission_time else None
256+
),
257+
"score": score,
258+
"passed": passed,
259+
"gpu_type": gpu_type,
260+
"mode": mode,
261+
"model": model_name,
262+
})
263+
264+
series_by_model = group_by_model(items)
265+
266+
total_time = (time.perf_counter() - total_start) * 1000
267+
logger.info(
268+
"[Perf] timeseries leaderboard_id=%s | query=%.2fms | total=%.2fms",
269+
leaderboard_id, query_time, total_time,
270+
)
271+
272+
return http_success(data={
273+
"leaderboard_id": leaderboard_id,
274+
"time_series": series_by_model,
275+
})
276+
277+
278+
def parse_model_from_filename(file_name: str) -> str:
279+
"""
280+
Extract model name from file names like:
281+
- matmul_py_H100_claude-opus-4.5_ka_submission.py -> claude-opus-4.5
282+
- matmul_py_H100_gpt-5-2_ka_submission.py -> gpt-5-2
283+
- matmul_py_H100_gpt-5_ka_submission.py -> gpt-5
284+
- 1.py -> 1.py (no match, return as-is)
285+
"""
286+
if not file_name:
287+
return "unknown"
288+
289+
# Pattern: {problem}_py_{gpu}_{model}_ka_submission.py
290+
pattern = r"^.+_py_[A-Za-z0-9]+_(.+?)_ka_submission\.py$"
291+
match = re.match(pattern, file_name)
292+
if match:
293+
return match.group(1)
294+
295+
return file_name
296+
297+
298+
def group_by_model(items: List[dict]) -> dict:
299+
"""
300+
Group time series items by model name for easier charting.
301+
"""
302+
series = {}
303+
for item in items:
304+
model = item.get("model", "unknown")
305+
if model not in series:
306+
series[model] = []
307+
series[model].append({
308+
"submission_time": item["submission_time"],
309+
"score": item["score"],
310+
"submission_id": item["submission_id"],
311+
})
312+
return series

0 commit comments

Comments
 (0)