Architecture Overview¶
This document provides a comprehensive overview of the Quizzical Beats architecture, designed to help developers understand the system structure and components.
Application Structure¶
Quizzical Beats follows a modular Flask application structure:
musicround/
├── __init__.py # Application factory
├── config.py # Configuration management
├── models.py # Database models
├── version.py # Version information
├── errors.py # Error handling
├── deezer_client.py # Deezer API integration
├── helpers/ # Utility modules
│ ├── __init__.py
│ ├── auth_helpers.py # Authentication utilities
│ ├── backup_helper.py # Backup management
│ ├── dropbox_helper.py # Dropbox integration
│ ├── email_helper.py # Email functionality
│ ├── import_helper.py # Song import utilities
│ ├── metadata.py # Song metadata processing
│ ├── spotify_direct.py # Spotify API client
│ └── utils.py # General utilities
├── mp3/ # Audio file storage
├── routes/ # Route definitions
│ ├── __init__.py
│ ├── api.py # API endpoints
│ ├── auth.py # Authentication routes
│ ├── core.py # Core application routes
│ ├── db_admin.py # Database administration
│ ├── deezer_routes.py # Deezer integration
│ ├── generate.py # Content generation
│ ├── import.py # Generic import functionality
│ ├── import_routes.py # Import interface routes
│ ├── import_songs.py # Song import functionality
│ ├── process.py # Audio processing
│ ├── rounds.py # Quiz round management
│ └── users.py # User account management
├── static/ # Static files (CSS, JS, images)
└── templates/ # Jinja2 HTML templates
├── admin/ # Admin interface templates
├── auth/ # Authentication templates
└── ... (other template categories)
Key Components¶
Application Factory¶
The application is initialized using a factory pattern in __init__.py. This allows for flexible configuration and testing:
def create_app():
app = Flask(__name__)
# Load configuration
app.config.from_object(Config)
# Initialize extensions
db.init_app(app)
login_manager.init_app(app)
# Register blueprints
from musicround.routes import core, auth, rounds, users, import_songs, import_routes, generate, process, api, deezer_routes, db_admin
app.register_blueprint(core.bp)
app.register_blueprint(auth.bp)
app.register_blueprint(rounds.bp)
app.register_blueprint(users.bp)
app.register_blueprint(import_songs.bp)
app.register_blueprint(import_routes.bp)
app.register_blueprint(generate.bp)
app.register_blueprint(process.bp)
app.register_blueprint(api.bp)
app.register_blueprint(deezer_routes.bp)
app.register_blueprint(db_admin.bp)
return app
Configuration Management¶
Configuration is handled in config.py using environment variables loaded from a .env file:
class Config:
# Core configuration
DEBUG = os.getenv("DEBUG", "True") == "True"
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-key-please-change')
# API keys for various services
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
DEEPL_API_KEY = os.getenv("DEEPL_API_KEY")
MEANINGCLOUD_API_KEY = os.getenv("MEANINGCLOUD_API_KEY")
LASTFM_API_KEY = os.getenv("LASTFM_API_KEY")
# Database configuration
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI', 'sqlite:///data/song_data.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
# OAuth provider configurations
SPOTIFY_CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
SPOTIFY_CLIENT_SECRET = os.getenv("SPOTIFY_CLIENT_SECRET")
DROPBOX_APP_KEY = os.getenv("DROPBOX_APP_KEY")
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
# ... other configuration
Database Models¶
The data model is defined in models.py using SQLAlchemy ORM:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=True)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
rounds = db.relationship('Round', backref='author', lazy=True)
# OAuth tokens and preferences
class Song(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
artist = db.Column(db.String(200), nullable=False)
spotify_id = db.Column(db.String(50), nullable=True)
preview_url = db.Column(db.String(255), nullable=True)
year = db.Column(db.Integer, nullable=True)
# Audio features and metadata
class Round(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
songs = db.relationship('RoundSong', backref='round', lazy=True, cascade="all, delete-orphan")
# Round configuration and settings
Authentication System¶
The authentication system supports:
- Local Authentication: Username/password authentication
- OAuth Providers:
- Spotify
- Authentik (OpenID Connect)
- Role-Based Access Control: Admin vs. regular users
OAuth integration is handled through dedicated helper functions in auth_helpers.py:
def get_spotify_oauth():
# Configure OAuth for Spotify
def get_google_oauth():
# Configure OAuth for Google
def get_authentik_oauth():
# Configure OAuth for Authentik
External Integrations¶
Spotify Integration¶
The spotify_direct.py module provides:
- Authentication with Spotify API
- Playlist import functionality
- Track search and metadata retrieval
- Audio feature access
Dropbox Integration¶
The dropbox_helper.py module enables:
- OAuth authentication with Dropbox
- File export to Dropbox
- Folder management in Dropbox
- Shared link generation
Deezer Integration¶
The deezer_client.py and related routes provide:
- Authentication with Deezer API
- Playlist import
- Track search and preview access
OpenAI Integration¶
AI-powered features use the OpenAI API for: - Round generation suggestions - Lyric analysis - Song categorization
Backup System¶
The backup system in backup_helper.py provides:
def create_backup(include_mp3=True, include_config=True, backup_name=None):
# Create ZIP archive with database and optional files
def restore_from_backup(backup_file, force=False):
# Restore system from backup archive
def list_backups():
# List available backups with metadata
def verify_backup(backup_path):
# Check backup integrity
Features include: - Database dumps using SQLite backup API - MP3 file inclusion in backups - Configuration file backup - Scheduled backups - Retention policy management
Request Flow¶
- Request arrives at the Flask application
- Blueprint routes direct to the appropriate view function
- Authentication middleware checks for required permissions
- View function processes the request:
- Database queries via SQLAlchemy models
- External API calls where needed
- Business logic processing
- Response is rendered using Jinja2 templates
- Rendered HTML is returned to the client
Example Routes¶
@bp.route('/rounds/<int:round_id>')
@login_required
def view_round(round_id):
round = Round.query.get_or_404(round_id)
# Check permissions
# Process data
return render_template('rounds/view.html', round=round)
@bp.route('/rounds/<int:round_id>/export-to-dropbox', methods=['POST'])
@login_required
def export_to_dropbox(round_id):
round = Round.query.get_or_404(round_id)
# Check permissions
# Export to Dropbox
return jsonify({'success': True, 'message': 'Export successful'})
System Health Monitoring¶
The health monitoring system provides dashboards for:
- Database Health: Connection status, table counts, size
- Storage Health: Directory status, file counts, permissions
- External Service Status: API connectivity checks
- Version Information: Application version, dependencies
Extension Points¶
To extend Quizzical Beats, consider these integration points:
- New OAuth Providers: Add provider configuration in
auth_helpers.py - Additional Export Formats: Implement in the rounds routes
- New Music Data Sources: Create a new client module similar to
spotify_direct.pyordeezer_client.py - Custom Audio Processing: Extend the functionality in the
process.pyroutes - AI Features: Enhance OpenAI integration for additional content generation
Technology Stack¶
- Backend: Python 3.8+, Flask 2.x
- Database: SQLAlchemy 1.4+ with SQLite/PostgreSQL/MySQL
- Frontend: TailwindCSS, Alpine.js, vanilla JavaScript
- Authentication: Flask-Login, OAuth integrations
- APIs: Spotify, Deezer, Dropbox, OpenAI, DeepL
- Media Processing: FFmpeg, MP3 manipulation libraries
- Testing: Pytest for unit and integration tests