# Music Analyser

A personal analytics dashboard for your music listening habits, powered by Python, FastAPI, React, and Google Gemini AI.

![Dashboard Screenshot](screen.png)

## Features

- **Continuous Ingestion**: Polls Spotify every 60 seconds to record your listening history.
- **Data Enrichment**: 
  - **Genres & Images** (via Spotify)
  - **Audio Features** (Energy, BPM, Mood via ReccoBeats)
  - **Lyrics & Metadata** (via Genius)
- **Dashboard**: A responsive UI with Tailwind CSS, featuring AI-generated narrative insights.
- **AI Powered**: Google Gemini generates personalized listening narratives and roasts.

## Quick Start (Docker Compose)

### 1. Prerequisites
- Docker & Docker Compose installed
- Spotify Developer Credentials ([Create App](https://developer.spotify.com/dashboard))
- Google Gemini API Key ([Get Key](https://aistudio.google.com/app/apikey))
- Genius API Token (Optional, for lyrics - [Get Token](https://genius.com/api-clients))

### 2. Get Spotify Refresh Token

Run this one-time script locally to authorize your Spotify account:

```bash
cd backend
pip install httpx
python scripts/get_refresh_token.py
```

Follow the prompts. Copy the `refresh_token` value for your `.env` file.

### 3. Create `.env` File

Create a `.env` file in the project root:

```bash
SPOTIFY_CLIENT_ID="your_client_id"
SPOTIFY_CLIENT_SECRET="your_client_secret"
SPOTIFY_REFRESH_TOKEN="your_refresh_token"
GEMINI_API_KEY="your_gemini_key"
GENIUS_ACCESS_TOKEN="your_genius_token"  # Optional
```

### 4. Run with Pre-built Images

```bash
# Pull the latest images
docker pull ghcr.io/bnair123/musicanalyser:latest
docker pull ghcr.io/bnair123/musicanalyser-frontend:latest

# Start the services
docker-compose up -d
```

Or build from source:

```bash
docker-compose up -d --build
```

### 5. Access the Dashboard

Open your browser to: **http://localhost:8991**

## Architecture

```
┌─────────────────────┐     ┌─────────────────────┐
│     Frontend        │     │      Backend        │
│  (React + Vite)     │────▶│  (FastAPI + Worker) │
│   Port: 8991        │     │   Port: 8000        │
└─────────────────────┘     └─────────────────────┘
                                     │
                            ┌────────┴────────┐
                            ▼                 ▼
                      ┌──────────┐     ┌──────────────┐
                      │ SQLite   │     │ Spotify API  │
                      │ music.db │     │ Gemini AI    │
                      └──────────┘     └──────────────┘
```

- **Backend Container**: Runs both the FastAPI server AND the background Spotify polling worker
- **Frontend Container**: Nginx serving the React build, proxies `/api/` to backend
- **Database**: SQLite stored in a Docker named volume (`music_data`) for persistence

## Data Persistence

Your listening history is stored in a Docker named volume:
- Volume name: `music_data`
- Database file: `/app/music.db`
- Migrations run automatically on container startup

To backup your data:
```bash
docker cp $(docker-compose ps -q backend):/app/music.db ./backup.db
```

## Local Development

### Backend
```bash
cd backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt

# Run migrations
alembic upgrade head

# Start worker (polls Spotify every 60s)
python run_worker.py &

# Start API server
uvicorn app.main:app --reload
```

### Frontend
```bash
cd frontend
npm install
npm run dev
```

Access at http://localhost:5173 (Vite proxies `/api` to backend automatically)

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SPOTIFY_CLIENT_ID` | Yes | Spotify app client ID |
| `SPOTIFY_CLIENT_SECRET` | Yes | Spotify app client secret |
| `SPOTIFY_REFRESH_TOKEN` | Yes | Long-lived refresh token from OAuth |
| `GEMINI_API_KEY` | Yes | Google Gemini API key |
| `GENIUS_ACCESS_TOKEN` | No | Genius API token for lyrics |
| `DATABASE_URL` | No | SQLite path (default: `sqlite:///./music.db`) |
