docs: rewrite README for public readiness
- Added 'Under Active Development' caveat - Documented all features: auth modes, admin CLI, artwork, metadata, favorites - Full configuration table with KITHARA_MODE, admin credentials, defaults - Auth modes section explaining single vs multi user - Admin CLI usage examples - Complete API reference (clips, auth, admin endpoints) - Architecture diagram - Roadmap with 6 phases - Development instructions (tests, type checking) - Updated models table with status indicators - License: MIT — Hardcore will never die
This commit is contained in:
1 parent
674abbbe8f
commit
dcc358fa9b
1 file changed
+198
-18
@@ -1,11 +1,49 @@
|
|||||||
# Kithara Studio
|
# 🎵 Kithara Studio
|
||||||
|
|
||||||
A webapp for generating, playing, and storing music clips using Google's Lyria music generation models.
|
A self-hosted webapp for generating, playing, and managing music clips using Google's Lyria music generation models.
|
||||||
|
|
||||||
Built by Kagamine Rin & Ryan.
|
Built by [Kagamine Rin](https://rin.captcouch.xyz) & 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
|
## Quick Start
|
||||||
|
|
||||||
|
### Docker (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone and configure
|
||||||
|
git clone https://github.com/your-org/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
|
```bash
|
||||||
# Backend
|
# Backend
|
||||||
cd backend
|
cd backend
|
||||||
@@ -13,37 +51,179 @@ python -m venv .venv
|
|||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
cd src
|
cd src
|
||||||
uvicorn main:app --reload
|
uvicorn main:app --reload --port 8000
|
||||||
|
|
||||||
# Frontend (new terminal)
|
# Frontend (new terminal)
|
||||||
cd frontend
|
cd frontend
|
||||||
npm install
|
npm install
|
||||||
npm run dev
|
npm run dev
|
||||||
|
# Open http://localhost:5173
|
||||||
```
|
```
|
||||||
|
|
||||||
## Architecture
|
---
|
||||||
|
|
||||||
- **Backend**: FastAPI (Python) — async API client for Google's Lyria models, SQLite metadata, file storage
|
## Configuration
|
||||||
- **Frontend**: React + Vite + TypeScript + Tailwind — dark theme, audio player
|
|
||||||
- **Storage**: SQLite for clip metadata, local filesystem for MP3 files
|
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
|
## API
|
||||||
|
|
||||||
| Endpoint | Method | Description |
|
| Endpoint | Method | Description |
|
||||||
|----------|--------|-------------|
|
|----------|--------|-------------|
|
||||||
| `/api/health` | GET | Health check |
|
| `GET /api/health` | — | Health check (includes mode: single/multi) |
|
||||||
| `/api/generate` | POST | Start clip generation |
|
| **Clips** | | |
|
||||||
| `/api/clips` | GET | List all clips |
|
| `POST /api/generate` | — | Start clip generation |
|
||||||
| `/api/clips/{id}` | GET | Get clip metadata |
|
| `GET /api/clips` | — | List clips |
|
||||||
| `/api/clips/{id}/audio` | GET | Stream MP3 |
|
| `GET /api/clips/{id}` | — | Clip metadata |
|
||||||
| `/api/clips/{id}` | DELETE | Delete clip |
|
| `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 │ │ │ │ │
|
||||||
|
└──────────────┘ └──────┬───────┘ └────────────┘
|
||||||
|
│ │
|
||||||
|
│ ┌─────▼──────┐
|
||||||
|
│ │ Lyria │
|
||||||
|
│ │ API │
|
||||||
|
│ └────────────┘
|
||||||
|
│
|
||||||
|
┌──────▼───────┐
|
||||||
|
│ 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
|
## Models
|
||||||
|
|
||||||
- **v0.1**: Google Lyria 3 Clip Preview (30s, REST)
|
| Version | Model | Duration | Status |
|
||||||
- **v0.2**: Google Lyria 3 Pro (structure-aware, ~3min)
|
|---------|-------|----------|--------|
|
||||||
- **v0.3**: Google Lyria RealTime (WebSocket streaming)
|
| v0.1 | Lyria 3 Clip Preview | ~30s | ✅ Active |
|
||||||
|
| v0.2 | Lyria 3 Pro | ~3min | 🔜 Planned |
|
||||||
|
| 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
|
## License
|
||||||
|
|
||||||
MIT — Hardcore will never die.
|
MIT — Hardcore will never die. 🎵
|
||||||
Reference in new issue
Block a user