File size: 2,464 Bytes
d665fdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""Minimal Flask app for Hugging Face Docker Space: landing, analysis, replay placeholder."""

from __future__ import annotations

from pathlib import Path

import duckdb
from flask import Flask, render_template, request

APP_DIR = Path(__file__).resolve().parent
DEMO_CSV = APP_DIR / "demo_data" / "demo_trials.csv"

PRESETS: list[dict[str, str]] = [
    {
        "id": "summary",
        "label": "Summary (count, mean RT, age range)",
        "sql": """
            SELECT
              COUNT(*)::INT AS n_trials,
              ROUND(AVG(rt_ms), 2) AS mean_rt_ms,
              MIN(age)::INT AS min_age,
              MAX(age)::INT AS max_age
            FROM read_csv_auto(?)
            """,
    },
    {
        "id": "by_age",
        "label": "Mean RT by age",
        "sql": """
            SELECT
              age,
              COUNT(*)::INT AS n_trials,
              ROUND(AVG(rt_ms), 2) AS mean_rt_ms
            FROM read_csv_auto(?)
            GROUP BY age
            ORDER BY age
            """,
    },
]

PRESET_CHOICES = [{"id": p["id"], "label": p["label"]} for p in PRESETS]


def create_app() -> Flask:
    app = Flask(__name__, static_folder="static", template_folder="templates")

    @app.get("/health")
    def health() -> tuple[str, int]:
        return "ok", 200

    @app.get("/")
    def landing():
        return render_template("landing.html")

    @app.get("/analysis")
    def analysis():
        preset_id = (request.args.get("preset") or "summary").strip()
        preset = next((p for p in PRESETS if p["id"] == preset_id), PRESETS[0])
        error: str | None = None
        table_html: str | None = None
        if not DEMO_CSV.is_file():
            error = f"Demo data missing at {DEMO_CSV}"
        else:
            try:
                con = duckdb.connect(database=":memory:")
                rel = con.execute(preset["sql"], [str(DEMO_CSV)])
                df = rel.fetchdf()
                table_html = df.to_html(classes="data", index=False, border=0)
            except Exception as exc:  # noqa: BLE001 — surface query errors in the UI
                error = str(exc)

        return render_template(
            "analysis.html",
            presets=PRESET_CHOICES,
            current_preset=preset["id"],
            table_html=table_html,
            error=error,
        )

    @app.get("/replay")
    def replay():
        return render_template("replay.html")

    return app


app = create_app()