Annotation Admin

← Dashboard

README.md · last modified 2026-05-27 17:49

sa_annotation_client

FastAPI-based sound annotation tool with two web apps:
- Client app for annotators (audio playback + label selection)
- Admin app for session management, config/template editing, and in-window client previews

What this project does

Requirements

Installation

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Running

Start the apps in separate terminals.

1) Client app

python3 main.py

The client listens on the port configured in session_config.toml ([session].port, default 5020).

2) Admin app

python3 admin.py

Admin runs on 127.0.0.1:5021.

App URLs

If base_path is configured (see below), client routes are served under that prefix (for example /sa-annotation).

Admin workflow

  1. Open admin dashboard.
  2. Activate a session.
  3. Edit session config and annotation template in Edit.
  4. Use embedded previews:
  5. Welcome preview
  6. Annotation preview
  7. Self-test preview

When saving config/template for the active session, admin rewrites root session_config.toml so the client immediately uses updated values.

How to run an annotation project (operator checklist)

  1. Open /sa-annotation-admin and log in as admin-tjeerd.
  2. Create a new session (usually copied from Default) or select an existing one.
  3. Set up audio clips using the convention below, then point session.audio_dir to that folder.
  4. In Edit, update session settings (welcome text, languages, state windows, and audio dir).
  5. Use Test in admin to validate config, template, and audio availability.
  6. Activate the session to make it live for the client app.
  7. Verify annotator flow in /sa-annotation (welcome → start → playback → submit).
  8. Monitor participation and counts via Monitor.
  9. After completion, export NDJSON files from the session annotations folder.

MP3 folder convention

Sessions and active config

Session config (session_config.toml)

Example structure:

[session]
name = "Stadsgeluiden in Haarlem"
location = "Haarlem, venue X"
timezone = "Europe/Amsterdam"
audio_dir = "/absolute/path/to/mp3s"
annotation_template = "acoustic_annotations_urban_NL.toml"
annotations_dir = "annotations"
port = 5020
base_path = "/sa-annotation"
language = "nl"
languages = ["nl", "en"]

[welcome]
text_nl = "Welkom bij de annotatiesessie."
text_en = "Welcome to the annotation session."

[state.testing]
start = "2026-04-22T09:00:00+02:00"
end = "2026-04-29T19:30:00+02:00"
welcome_text_nl = "Annotatietest om je computer en geluid te testen."
welcome_text_en = "Test annotation to verify your computer and audio setup."
max_clips = 3
annotations_dir = "annotations_testing"

[state.annotation_session]
start = "2026-04-29T19:30:00+02:00"
end = "2026-04-29T23:30:00+02:00"
welcome_text_nl = "Annotatie sessie van stadse geluiden in het centrum van Haarlem"
welcome_text_en = "Annotation session for urban sounds in the center of Haarlem."

[state.free_online]
start = "2026-04-29T23:30:00+02:00"
end = "2026-05-20T23:59:00+02:00"
welcome_text_nl = "Open online annotatie."
welcome_text_en = "Open online annotation."

[state.not_open]
start = "2026-05-20T23:59:00+02:00"
end = "2026-06-30T23:59:00+02:00"
welcome_text_nl = "Op dit moment is er niets te annoteren."
welcome_text_en = "There is currently nothing to annotate."

[email]
enabled = true
message_nl = "Als je je email adres achterlaat kunnen we je op de hoogte houden van ontwikkeling."
message_en = "If you leave your email address, we can keep you informed about developments."
placeholder_nl = "naam@voorbeeld.nl"
placeholder_en = "name@example.com"

Notes

Annotation template format

Annotation labels are loaded from a TOML file under nested timescale/category sections:

[second.human]
labels = ["speaker", "laughter"]

[minute.transport]
labels = ["traffic", "train"]

Data storage

Language handling

Tailscale Funnel deployment (path-based)

For deployment at a subpath (for example https://<node>.ts.net/sa-annotation):
1. Set [session].base_path = "/sa-annotation" in session_config.toml.
2. Start the client app on the configured port (default 5020).
3. Configure Funnel path mapping:

tailscale funnel --bg --https=443 --set-path=/sa-annotation localhost:5020
  1. Verify with:
tailscale funnel status

Compatibility hardening

Quick validation commands

python3 -m py_compile main.py admin.py config.py i18n.py
python3 - <<'PY'
try:
    import tomllib
except ModuleNotFoundError:
    import tomli as tomllib
for p in ["session_config.toml", "sessions/Default/session_config.toml"]:
    with open(p, "rb") as f:
        tomllib.load(f)
print("TOML OK")
PY

Deploy to mini

Use the included deploy script to sync updates to the mini, restart client/admin services, and run health checks.

./deploy_to_mini.sh

Optional: provide a different SSH host alias (default is mac-mini):

./deploy_to_mini.sh <ssh-host-alias>

Troubleshooting