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>
55 lines
No EOL
2.1 KiB
Python
55 lines
No EOL
2.1 KiB
Python
# SPDX-License-Identifier: GPL-3.0-only
|
|
"""Server configuration, loaded from environment / .env (see .env.example).
|
|
|
|
Everything points at self-hosted services by default: local object storage, a local
|
|
Ollama, and a local faster-whisper model. Nothing here requires a proprietary cloud.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_prefix="NIGHTJAR_", env_file=".env")
|
|
|
|
# API
|
|
api_token: str = "change-me" # bearer token for write endpoints
|
|
|
|
# Storage: "local" | "s3" | "webdav"
|
|
storage_backend: str = "local"
|
|
local_media_dir: str = "./media"
|
|
|
|
# S3-compatible (MinIO) - used when storage_backend == "s3"
|
|
s3_endpoint: str = "http://localhost:9000"
|
|
s3_bucket: str = "openscribe"
|
|
s3_access_key: str = ""
|
|
s3_secret_key: str = ""
|
|
|
|
# Metadata DB (SQLite to start; Postgres URL later)
|
|
database_url: str = "sqlite:///./openscribe.db"
|
|
|
|
# --- AI providers (see docs/ai-providers.md) --------------------------------------
|
|
# Transcription provider: "local_whisper" (self-hosted) | "openai_compatible"
|
|
transcription_provider: str = "local_whisper"
|
|
transcription_base_url: str = "" # e.g. https://api.openai.com/v1 or a Groq/local URL
|
|
transcription_api_key: str = ""
|
|
transcription_model: str = "" # e.g. whisper-1, whisper-large-v3
|
|
|
|
# LLM provider for summaries + Ask-AI:
|
|
# "ollama" (default, self-hosted) | "openai_compatible" | "anthropic"
|
|
llm_provider: str = "ollama"
|
|
llm_base_url: str = "https://api.openai.com/v1" # used by openai_compatible
|
|
llm_api_key: str = ""
|
|
llm_model: str = "" # per-provider default applied if empty
|
|
|
|
# Local faster-whisper (used when transcription_provider == local_whisper)
|
|
whisper_model: str = "base" # tiny|base|small|medium|large-v3
|
|
whisper_device: str = "cpu" # cpu|cuda
|
|
whisper_compute_type: str = "int8"
|
|
|
|
# Local Ollama (used when llm_provider == ollama)
|
|
ollama_url: str = "http://localhost:11434"
|
|
ollama_model: str = "llama3.1"
|
|
|
|
|
|
settings = Settings() |