psyche / app.py
younesStrittmatter's picture
Add hugging face space setup
d665fdc
Raw
History Blame Contribute Delete
2.46 kB
"""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()