openscribe/server
Laurence 19c3e156a0
Some checks failed
ci / firmware (pull_request) Failing after 2s
ci / openapi (pull_request) Failing after 32s
ci / emulator (pull_request) Failing after 35s
ci / server (pull_request) Failing after 29s
feat(web): Nightjar web app - Plaud-style record/transcribe/summarise UI
A runnable, self-hosted web interface so the whole workflow can be tested end to
end: record or upload audio in the browser, watch it transcribe and summarise,
browse a library, play back, and export.

What changed:
- server/app/store.py: SQLite + on-disk audio storage for recordings (stdlib only).
- server/app/pipeline.py: background task audio -> transcribe -> summarise via the
  existing provider layer, updating status (queued/transcribing/summarising/done/error).
- server/app/main.py: web API - POST upload, list, detail, audio (Range), delete, and
  export (txt/md/srt/vtt/json) - and serves the SPA at /.
- server/app/web/: Plaud-style single-page UI (index.html, styles.css, app.js). Sidebar
  library, in-browser recording (MediaRecorder) + file upload, live status polling,
  audio player, summary (overview/key points/actions), timestamped transcript, exports.
- server/Dockerfile + README: two-minute run instructions (default provider: Groq free
  tier for both Whisper + LLM), and a Docker option.
- config: env prefix switched OPENSCRIBE_ -> NIGHTJAR_ to match the brand and the site
  tutorials; .env.example rewritten with a ready Groq quick-start.
- state/TODO: web app recorded as done.

Why:
- User asked for a Plaud-like web interface to test how it all works. Nothing testable
  existed before (marketing site is a brochure; pipeline was unwired). This delivers a
  real, runnable product demo and effectively lands M5/M6 for the HTTP providers.

Notes:
- Slim by design: AI is offloaded to the configured provider, so no local ML deps needed
  for the demo. Byte-compiles clean; JS passes node --check. Local faster-whisper still
  needs its model (M5) for the fully-offline path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 09:57:42 +01:00
..
app feat(web): Nightjar web app - Plaud-style record/transcribe/summarise UI 2026-07-06 09:57:42 +01:00
Dockerfile feat(web): Nightjar web app - Plaud-style record/transcribe/summarise UI 2026-07-06 09:57:42 +01:00
README.md feat(web): Nightjar web app - Plaud-style record/transcribe/summarise UI 2026-07-06 09:57:42 +01:00
requirements.txt feat(server): pluggable AI providers - any open-standard or commercial AI 2026-07-03 18:56:58 +01:00

Nightjar server + web app

A self-hosted FastAPI app with a Plaud-style web interface: upload or record audio in the browser, watch it transcribe and summarise, browse a library, play back, and export. The AI is done by whichever providers you configure, so you own the whole pipeline.

Try it in two minutes

You need one AI key. The default config uses Groq (free tier, fast Whisper + LLM) for both transcription and summaries.

cd server
python -m venv .venv
. .venv/bin/activate            # Windows:  .venv\Scripts\activate
pip install fastapi "uvicorn[standard]" pydantic pydantic-settings python-multipart httpx anthropic
cp .env.example .env            # then paste your Groq key into .env (both API_KEY lines)
uvicorn app.main:app --reload

Open http://localhost:8000 and press Record (or Upload an audio file). It will show transcribing… → summarising… → done, then the transcript, a summary with key points and action items, an audio player, and export buttons (TXT / Markdown / SRT / VTT / JSON).

Confirm your providers loaded at http://localhost:8000/health.

Or with Docker

cd server
docker build -t nightjar .
docker run -p 8000:8000 --env-file .env -v "$PWD/media:/app/media" nightjar

Choosing a different AI

Everything is set in .env (see .env.example and docs/ai-providers.md): OpenAI or any OpenAI-compatible endpoint, Anthropic Claude, or fully local (Ollama + faster-whisper for a "nothing leaves my machine" setup). Change the vars, restart, done.

What's inside

app/main.py       FastAPI: upload/list/detail/audio/export + serves the web UI
app/pipeline.py   audio -> transcribe -> summarise (background task)
app/store.py      recordings in SQLite, audio on disk (demo storage)
app/providers/    the pluggable transcription + LLM providers
app/web/          the Plaud-style single-page UI (no build step)

This is the demo/single-node app. The hosted multi-tenant service (metering, billing, object storage, Postgres, the Private-tier GPU node) is described in ../docs/hosted-service.md and ../docs/infrastructure.md.

Notes

  • Recordings and the SQLite index live under NIGHTJAR_LOCAL_MEDIA_DIR (default ./media).
  • Browser recording produces WebM/Opus, which Groq and OpenAI accept directly - no ffmpeg needed for the demo.
  • The API contract for the device/server is ../api/openapi.yaml.