Metadata-Version: 2.4
Name: songhive
Version: 0.0.11
Summary: A federated and self-hosted music sharing service
Author-email: Fabio Manganiello <fabio@manganiello.tech>
Project-URL: homepage, https://git.platypush.tech/blacklight/songhive
Project-URL: repository, https://git.platypush.tech/blacklight/songhive
Keywords: music,activitypub,fediverse,indieweb,streaming
Classifier: Topic :: Utilities
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Development Status :: 3 - Alpha
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.100.0
Requires-Dist: pydantic>=2.4.0
Requires-Dist: pydantic-settings>=2.4.0
Requires-Dist: sqlalchemy[asyncio]>=2.0
Requires-Dist: alembic>=1.18.0
Requires-Dist: asyncpg>=0.28
Requires-Dist: psycopg2-binary>=2.9
Requires-Dist: uvicorn>=0.23
Requires-Dist: tornado>=6.5.7
Requires-Dist: a2wsgi>=1.7
Requires-Dist: websockets>=11.0
Requires-Dist: bcrypt>=4.0
Requires-Dist: PyJWT>=2.13.0
Requires-Dist: authlib>=1.6.12
Requires-Dist: python-multipart>=0.0.31
Requires-Dist: celery>=5.3
Requires-Dist: redis>=5.0
Requires-Dist: aiofiles>=23.2.1
Requires-Dist: aioboto3>=12.4.0
Requires-Dist: boto3>=1.28
Requires-Dist: mutagen>=1.47
Requires-Dist: musicbrainzngs>=0.7.1
Requires-Dist: pubby>=0.2.22
Requires-Dist: tomli>=2.0; python_version < "3.11"
Requires-Dist: httpx>=0.24
Requires-Dist: email-validator>=2.0
Dynamic: license-file

# Songhive

[![Build Status](https://ci-cd.platypush.tech/api/badges/blacklight/songhive/status.svg)](https://ci-cd.platypush.tech/blacklight/songhive)
[![Coverage Badge](https://app.codacy.com/project/badge/Coverage/f8740f0a9f7e40f0a134441bd5570690)](https://app.codacy.com/gh/blacklight/songhive/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f8740f0a9f7e40f0a134441bd5570690)](https://app.codacy.com/gh/blacklight/songhive/dashboard)
[![CodeFactor](https://www.codefactor.io/repository/github/blacklight/songhive/badge)](https://www.codefactor.io/repository/github/blacklight/songhive)
[![Github stars](https://img.shields.io/github/stars/blacklight/songhive?style=flat&logo=Github)](https://github.com/blacklight/songhive)
[![Github forks](https://img.shields.io/github/forks/blacklight/songhive?style=flat&logo=Github)](https://github.com/blacklight/songhive)
[![Last Commit](https://img.shields.io/github/last-commit/BlackLight/songhive.svg)](https://git.platypush.tech/songhive/songhive/commits/branch/main)
[![License](https://img.shields.io/github/license/blacklight/songhive.svg)](https://git.platypush.tech/blacklight/songhive/src/branch/main/LICENSE)

<!-- toc -->

- [Overview](#overview)
- [Features](#features)
- [Architecture](#architecture)
- [Installation](#installation)
  * [Docker](#docker)
    + [Latest image](#latest-image)
    + [From a local checkout](#from-a-local-checkout)
  * [pip](#pip)
    + [Latest stable package](#latest-stable-package)
    + [From a local checkout](#from-a-local-checkout-1)
  * [nginx setup](#nginx-setup)
- [Configuration](#configuration)
  * [Getting the default configuration](#getting-the-default-configuration)
  * [Base configuration](#base-configuration)
  * [From environment variables](#from-environment-variables)
- [Running the service](#running-the-service)
  * [Docker installation](#docker-installation)
  * [pip installation](#pip-installation)
    + [Celery](#celery)
  * [Creating the admin user](#creating-the-admin-user)
    + [Docker installation](#docker-installation-1)
    + [pip installation](#pip-installation-1)
- [Testing the installation](#testing-the-installation)
- [Development](#development)
  * [Frontend](#frontend)
- [API](#api)
- [License](#license)

<!-- tocstop -->

A federated and self-hosted music sharing service, built with ActivityPub
federation support.

## Overview

Songhive is a music streaming platform similar to
[Funkwhale](https://funkwhale.audio), with a focus on better federation. It
allows users to upload, organize, and stream their music library while
federating with other instances (including Mastodon) via ActivityPub.

## Features

- **Music Library**: Upload and organize artists, albums, and tracks
- **Streaming**: Audio streaming with on-the-fly transcoding (MP3, OGG, FLAC, AAC, Opus)
- **Metadata Enrichment**: Fetch metadata from external services
- **Federation**: ActivityPub support via [pubby](https://github.com/blacklight/pubby) — federate with Mastodon and other AP-compatible services
- **Playlists & Radios**: Create playlists and dynamic radio stations
- **Multi-user**: User registration, profiles, and admin management
- **OAuth2 Provider**: Third-party app authorization
- **Subsonic API**: Compatibility layer for Subsonic clients
- **Flexible Storage**: Local filesystem or S3-compatible object storage

## Architecture

- **Backend**: FastAPI (REST API) + Tornado (WebSocket, streaming, process server)
- **Models**: Pydantic (validation) + SQLAlchemy (async ORM)
- **Tasks**: Celery + Redis (background import, transcoding, federation delivery)
- **Frontend**: Vue.js 3 + TypeScript + Pinia

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed architecture documentation.

## Installation

Songhive can be run either as a complete Docker stack or installed locally with
`pip`.

### Docker

The Docker Compose setup builds the frontend and backend images, starts
PostgreSQL and Redis, and wires everything together behind an Nginx reverse
proxy. The `songhive`, `worker`, `postgres` and `redis` services all run as the
same non-root UID/GID as the host user, so the files in `./volumes` are owned by
you and are easy to access from the host.

#### Latest image

```bash
# Run the docker-compose bootstrap script
curl -fsSL https://git.fabiomanganiello.com/songhive/raw/branch/main/docker/bootstrap.sh | sh
```

#### From a local checkout

```bash
# Clone the repository
git clone https://git.fabiomanganiello.com/songhive
# Or from GitHub: git clone https://github.com/blacklight/songhive
cd songhive

# Set the UID/GID to match the host user (the same value is used by all
# rootless services and by the setup step that fixes volume permissions).
export PUID=$(id -u)
export PGID=$(id -g)

# Build the images
docker compose build
```

### pip

This path is useful for local development or running on an existing Python host.
A published package is also available on PyPI and ships the built web UI, so the
frontend does not need to be built manually when installing from PyPI.

Prerequisites:

- Python >= 3.10
- PostgreSQL (a SQLite database will also work, but it's not recommended for
  large installations)
- Redis/Valkey
- ffmpeg
- Node.js and npm (for the frontend)

#### Latest stable package

```bash
# Install from PyPI
pip install songhive
```

#### From a local checkout

Or, clone the repository and install in editable mode for development

```bash
git clone https://git.fabiomanganiello.com/songhive
# Or from GitHub: git clone https://github.com/blacklight/songhive
cd songhive

# Optional: create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

pip install -e .

# Build the web UI (outputs to songhive/static/)
cd frontend
npm install
npm run build
cd ..
```

### nginx setup

If you are planning to serve Songhive behind a reverse proxy, you can reuse the
[`nginx.conf`](./docker/nginx.conf) used by the Docker setup.

## Configuration

### Getting the default configuration

- If you installed Songhive through the docker-compose bootstrap script, then
  `config.toml` should be already downloaded under the same folder as
  `docker-compose.yml`.
- If you built Songhive from a local checkout, then copy the [example
  configuration file](./config.toml.example):

  ```bash
  cp config.toml.example config.toml
  ```
- Otherwise, download the latest `config.toml`:

  ```bash
  wget https://git.fabiomanganiello.com/songhive/raw/branch/main/config.toml.example
  ```

### Base configuration

Set at least the following values in `config.toml`:

```toml
[auth]
secret_key = "..."  # Generate with: python -c "import secrets; print(secrets.token_urlsafe(64))"

[storage]
local_path = "/path/to/writable/media"  # e.g. ./data/media

[server]
cors_origins = ["*"]  # Replace with your frontend origin(s) in production

[federation]
enabled = false  # Set a real instance_domain to enable federation
# instance_domain = "music.example.com"
```

### From environment variables

All the `config.toml` configuration entries can be overridden via environment
variables.

For example:

```toml
[database]
url = "postgresql+asyncpg://songhive:songhive@localhost:5432/songhive"
```

becomes:

```bash
SONGHIVE_DATABASE__URL="postgresql+asyncpg://songhive:songhive@localhost:5432/songhive"
```

## Running the service

### Docker installation

```bash
cd /path/to/your/songhive/installation
docker compose up -d
```

Then take down the stack with:

```bash
docker compose down
```

### pip installation

```bash
SONGHIVE_CONFIG="/path/to/your/songhive/installation/config.toml"
songhive -c "$SONGHIVE_CONFIG"
```

#### Celery

This is only required in a non-Docker setup. The Docker stack already runs a
separate container for the Celery workers.

Start the Celery worker in a second terminal:

```bash
celery -A songhive.tasks worker -B -l info
```

### Creating the admin user

#### Docker installation

```bash
cd /path/to/your/songhive/installation
docker compose exec songhive songhive admin create-user \
    --username admin \
    --email admin@example.com \
    --password secret \
    --admin
```

#### pip installation

```bash
SONGHIVE_CONFIG="/path/to/your/songhive/installation/config.toml"
songhive -c "$SONGHIVE_CONFIG" admin create-user \
    --username admin \
    --email admin@example.com \
    --password secret \
    --admin
```

## Testing the installation

Open:

- **Web UI**: http://localhost:8000/
- **Swagger UI** (only for the Docker setup): http://localhost:8000/swagger-ui/
- **OpenAPI spec**: http://localhost:8000/openapi.json

## Development

```bash
# Run tests
python -m pytest

# Run linting
python -m flake8 songhive tests

# Format code
python -m black .

# Start Celery worker
celery -A songhive.tasks worker -l info
```

### Frontend

```bash
cd frontend
npm install
npm run dev     # Development server
npm run build   # Production build (outputs to songhive/static/)
```

## API

REST API available at `/api/v1/`:

| Endpoint | Description |
|----------|-------------|
| `/api/v1/auth/` | Authentication (login, register, refresh) |
| `/api/v1/auth/api-tokens/` | API token management (create, list, revoke) |
| `/api/v1/users/` | User profiles |
| `/api/v1/artists/` | Artists |
| `/api/v1/albums/` | Albums |
| `/api/v1/tracks/` | Tracks |
| `/api/v1/playlists/` | Playlists |
| `/api/v1/libraries/` | User libraries |
| `/api/v1/favorites/` | Favorites |
| `/api/v1/history/` | Listening history |
| `/api/v1/radios/` | Dynamic radios |
| `/api/v1/stream/{id}` | Audio streaming |
| `/api/v1/admin/` | Admin endpoints |

WebSocket: `/ws/events` (real-time notifications)

Federation: `/.well-known/webfinger`, `/ap/actor`, `/ap/inbox`, `/ap/outbox`

## License

AGPL-3.0
