Minimalist Async Music Streamer
Mosic is a lightweight, high-performance backend for managing and streaming audio. Built on modern Python async foundations, it's designed to handle music uploads, metadata extraction, and streaming with minimal overhead.
It doesn't just store files; it understands them. Upload an audio file, and Mosic extracts the duration and tags automatically. It tracks play counts and exposes Prometheus metrics out of the box, making it ready for production monitoring.
- List Clips (
GET /play): Returns available sound clips with metadata (id, title, description, duration, audio_url). - Stream Clip (
GET /play/{id}/stream): Streams audio content and increments play counts in the database. - Clip Stats (
GET /play/{id}/stats): Returns play count and metadata for specific clips. - Database: PostgreSQL used for storing song metadata and play counts.
- Monitoring: Prometheus metrics exposed via
starlette_exporter. Grafana dashboard ready. - Add Clip (
POST /play): Endpoint to add new clip entries (supports both metadata-only and file upload). - CI/CD: GitHub Actions workflow configured for linting and testing.
- Security: API endpoints protected via API Key authentication.
- Core: Python 3.13+, FastAPI
- Data: SQLAlchemy (Async), PostgreSQL, Alembic
- Media: Mutagen (Metadata extraction)
- Ops: Starlette Exporter (Prometheus metrics)
- Package Manager: Poetry
- Python 3.13 or higher
- Poetry
- PostgreSQL instance
-
Clone and Install:
git clone https://github.com/flickowoa/mosic.git cd mosic poetry install -
Environment Setup: Create a
.envfile in the root directory. Configuration uses theMOSIC_prefix.MOSIC_DB_HOST=localhost MOSIC_DB_PORT=5432 MOSIC_DB_NAME=mosic MOSIC_DB_USER=postgres MOSIC_DB_PASSWORD=password # Or override the full URL directly # MOSIC_DATABASE_URL_OVERRIDE=postgresql+asyncpg://user:pass@localhost/mosic_db MOSIC_API_KEY=your_super_secret_key MOSIC_MEDIA_ROOT=./media
-
Database Migrations: Initialize the database schema:
poetry run alembic upgrade head
-
Run the Server:
poetry run fastapi dev app/main.py
The API will be available at
http://localhost:8000.
Send a POST request to /play/upload with an audio file. Mosic supports standard audio formats.
curl -X POST "http://localhost:8000/play/upload" \
-H "X-API-Key: your_api_key" \
-F "file=@/path/to/song.mp3"Stream a song by its ID. This endpoint supports range requests for seeking.
# GET /play/{song_id}/stream
http://localhost:8000/play/123e4567-e89b-12d3-a456-426614174000/streamSee how many times a track has been played.
# GET /play/{song_id}/stats
{
"song_id": "123e4567-e89b-12d3-a456-426614174000",
"play_count": 42
}Metrics are exposed at /metrics for Prometheus scraping.
mosic_request_latency_seconds: Histogram of request processing time.mosic_total_api_requests_total: Counter of total API requests.
Running Tests:
poetry run pytestLinting:
poetry run ruff check .