# šŸŽµ Kithara Studio A self-hosted webapp for generating, playing, and managing music clips using Google's Lyria music generation models. Built by Kagamine Rin & Ryan. > **āš ļø Under Active Development** > Kithara Studio is pre-1.0 software under rapid development. Features change, APIs shift, and things break. We use it daily and it works for us, but expect rough edges. Issues and feedback are welcome — PRs are welcome too if you're into that sort of thing. --- ## Features - **Music Generation** — Generate clips from text prompts using Google's Lyria models (currently Lyria 3 Clip Preview) - **Structured Prompts** — Build prompts with genre, mood, instrumentation, and description fields - **Maestro Mode** — Visual playback animation with cycling musical notes - **Audio Player** — Stream MP3 playback with waveform visualization - **Metadata & ID3 Tags** — Auto-detect BPM and key; set artist, album, genre, and comment; embed cover art and tags on download - **Artwork Generation** — AI-generated cover art via Gemini - **Favorites** — Heart clips to pin them (DB-backed, multi-user ready) - **Dark Theme** — Purpose-built dark UI for late-night production sessions - **Multi-User Auth** — Optional JWT auth with invite codes (single-user mode by default) - **Admin CLI** — `kithara-admin` for user management from the command line - **Docker Ready** — Full Docker Compose setup with Nginx reverse proxy --- ## Quick Start ### Docker (Recommended) ```bash # Clone and configure git clone https://gitea.captcouch.xyz/Public/kithara-studio.git cd kithara-studio cp .env.example .env # Edit .env — set your LYRIA_API_KEY # Launch docker compose up -d --build # Open http://localhost:3100 ``` ### Manual (Development) ```bash # Backend cd backend python -m venv .venv source .venv/bin/activate pip install -r requirements.txt cd src uvicorn main:app --reload --port 8000 # Frontend (new terminal) cd frontend npm install npm run dev # Open http://localhost:5173 ``` --- ## Configuration All configuration is via environment variables (`.env` file): | Variable | Default | Description | |----------|---------|-------------| | `LYRIA_API_KEY` | *(required)* | Google Lyria API key | | `LYRIA_DEFAULT_MODEL` | `lyria-3-clip-preview` | Default Lyria model | | `KITHARA_MODE` | `single` | `single` = no auth, `multi` = JWT auth required | | `KITHARA_ADMIN_USER` | `admin` | Bootstrap admin username (multi mode) | | `KITHARA_ADMIN_PASS` | `admin` | Bootstrap admin password (multi mode) | | `DEFAULT_ID3_ARTIST` | `Kagamine Rin` | Default artist tag | | `DEFAULT_ID3_ALBUM` | `Kithara Studio` | Default album tag | | `DEFAULT_ID3_GENRE` | `Hardcore Techno` | Default genre tag | | `TZ` | `America/New_York` | Timezone | ### Authentication Modes **Single-user mode** (`KITHARA_MODE=single`) — No login required. All clips belong to a default user. Best for personal use or trusted networks. **Multi-user mode** (`KITHARA_MODE=multi`) — JWT authentication required. Users register with invite codes. Admin user is bootstrapped on first startup. Best for shared deployments. --- ## Admin CLI Manage users and invite codes from the host: ```bash # List users python3 kithara-admin list-users # Create a user python3 kithara-admin create-user alice --password secret --role user # Create an invite code python3 kithara-admin create-invite python3 kithara-admin create-invite --max-uses 5 # List invite codes python3 kithara-admin list-invites # Change role python3 kithara-admin change-role alice admin # Reset password python3 kithara-admin reset-password alice newpass123 # Delete user (requires --confirm) python3 kithara-admin delete-user alice --confirm # Revoke invite code python3 kithara-admin revoke-invite CODE_HERE ``` > **Note:** The CLI reads `data/kithara.db` directly. If running in Docker, ensure the database file is writable by your host user, or run the CLI with appropriate permissions. --- ## API | Endpoint | Method | Description | |----------|--------|-------------| | `GET /api/health` | — | Health check (includes mode: single/multi) | | **Clips** | | | | `POST /api/generate` | — | Start clip generation | | `GET /api/clips` | — | List clips | | `GET /api/clips/{id}` | — | Clip metadata | | `GET /api/clips/{id}/audio` | — | Stream MP3 | | `PATCH /api/clips/{id}` | — | Update clip (title, metadata) | | `DELETE /api/clips/{id}` | — | Delete clip | | `POST /api/clips/{id}/favorite` | — | Toggle favorite | | **Artwork** | | | | `PATCH /api/clips/{id}/artwork` | — | Upload cover art | | `DELETE /api/clips/{id}/artwork` | — | Remove cover art | | `POST /api/clips/{id}/generate-artwork` | — | AI-generate cover art | | **Analysis** | | | | `GET /api/clips/{id}/analysis` | — | BPM and key detection | | **Auth** (multi mode) | | | | `POST /api/auth/login` | — | Login (returns JWT) | | `POST /api/auth/register` | — | Register (requires invite code) | | `GET /api/auth/me` | — | Current user info | | `PUT /api/auth/api-key` | — | Set per-user Lyria API key | | **Admin** (multi mode) | | | | `GET /admin/users` | — | List users | | `POST /admin/users` | — | Create user | | `DELETE /admin/users/{id}` | — | Delete user | | `PUT /admin/users/{id}/role` | — | Change user role | | `POST /admin/invites` | — | Create invite code | | `GET /admin/invites` | — | List invite codes | | `DELETE /admin/invites/{code}` | — | Revoke invite code | --- ## Architecture ``` ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Nginx │────>│ FastAPI │────>| SQLite │ │ (reverse │ │ Backend │ │ (data/) │ │ proxy) │ │ :8000 │ │ │ │ :3000 │ │ │ │ │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ | │ ā”Œā”€ā”€ā”€ā”€ā”€V──────┐ │ │ Lyria │ │ │ API │ │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ ā”Œā”€ā”€ā”€ā”€ā”€ā”€V───────┐ │ React + │ │ Vite + TS │ │ Tailwind │ │ (SPA) │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ``` - **Backend**: FastAPI (Python) — async API client for Google's Lyria models, SQLite metadata, file storage, JWT auth - **Frontend**: React + Vite + TypeScript + Tailwind — dark theme SPA with audio player and waveform visualization - **Storage**: SQLite for clip metadata + user data, local filesystem for MP3 files and cover art - **Auth**: JWT tokens (multi-user mode), bcrypt password hashing, invite-based registration --- ## Models | Version | Model | Duration | Status | |---------|-------|----------|--------| | v0.1 | Lyria 3 Clip Preview | ~30s | āœ… Active | | v0.2 | Lyria 3 Pro | ~3min | āœ… Active | | v0.3 | Lyria RealTime | Streaming | šŸ”œ Planned | --- ## Roadmap This is Phase 1 of a multi-phase roadmap: - [x] **Phase 1** — Users & Auth, `KITHARA_MODE` switch, admin CLI - [ ] **Phase 2** — Data isolation (per-user clip scoping) - [ ] **Phase 3** — Per-user Lyria API keys (BYOK) - [ ] **Phase 4** — Community gallery (sharing, discovery) - [ ] **Phase 5** — Remix (fork clips into new generations) - [ ] **Phase 6** — Email notifications (optional) --- ## Development ```bash # Run tests (requires librosa, librosa dependencies) cd backend pip install -r requirements.txt pytest tests/ -v # Type check frontend cd frontend npx tsc --noEmit ``` --- ## License MIT — Hardcore will never die. šŸŽµ