diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md new file mode 100644 index 0000000..f2e6765 --- /dev/null +++ b/DEPENDENCIES.md @@ -0,0 +1,140 @@ +# Dépendances du projet + +## Backend Python (requirements.txt) + +### Web Framework +- `fastapi==0.109.0` - Framework web moderne +- `uvicorn[standard]==0.27.0` - Serveur ASGI +- `python-multipart==0.0.6` - Support formulaires multipart + +### Database +- `sqlalchemy==2.0.25` - ORM +- `psycopg2-binary==2.9.9` - Driver PostgreSQL +- `pgvector==0.2.4` - Extension vecteurs PostgreSQL +- `alembic==1.13.1` - Migrations de base de données + +### Audio Processing +- `librosa==0.10.1` - Analyse audio +- `soundfile==0.12.1` - Lecture/écriture fichiers audio +- `audioread==3.0.1` - Décodage formats audio +- `mutagen==1.47.0` - Métadonnées ID3 + +### Machine Learning +- `essentia-tensorflow` - Classification genre/mood/instruments (installé via Dockerfile) +- `numpy==1.24.3` - Calcul numérique +- `scipy==1.11.4` - Calcul scientifique + +### Configuration & Validation +- `pydantic==2.5.3` - Validation de données +- `pydantic-settings==2.1.0` - Configuration via env vars +- `python-dotenv==1.0.0` - Chargement fichier .env +- `email-validator==2.1.0` - Validation emails (requis par Pydantic EmailStr) + +### Authentication +- `python-jose[cryptography]==3.3.0` - JWT tokens +- `passlib[bcrypt]==1.7.4` - Hashing passwords + +### Utilities +- `aiofiles==23.2.1` - I/O fichiers asynchrones +- `httpx==0.26.0` - Client HTTP asynchrone + +## Dépendances Système (Dockerfile) + +### Requis pour le backend +```bash +apt-get install -y \ + ffmpeg # Transcodage audio (MP3, etc.) + libsndfile1 # Lecture formats audio + gcc g++ gfortran # Compilation packages Python + libopenblas-dev # Algèbre linéaire optimisée + liblapack-dev # Routines algèbre linéaire + libfftw3-dev # Transformées de Fourier rapides + libavcodec-dev # Codecs audio/vidéo + libavformat-dev # Formats conteneurs + libavutil-dev # Utilitaires FFmpeg + libswresample-dev # Resampling audio + libsamplerate0-dev # Conversion taux d'échantillonnage + libtag1-dev # Métadonnées audio + libchromaprint-dev # Audio fingerprinting +``` + +## Frontend (package.json) + +### Framework +- `next@15.5.6` - Framework React +- `react@19.0.0` - Bibliothèque UI +- `react-dom@19.0.0` - Rendu React + +### State Management & Data Fetching +- `@tanstack/react-query@5.62.11` - Gestion état serveur +- `axios@1.7.9` - Client HTTP + +### UI & Styling +- `tailwindcss@3.4.17` - Framework CSS utility-first + +### Types +- `typescript@5.7.2` - Typage statique +- `@types/react@19.0.1` +- `@types/node@22.10.1` + +## Modèles Essentia (inclus dans le repo) + +Total: ~28 MB + +- `discogs-effnet-bs64-1.pb` (18 MB) - Modèle d'embedding +- `genre_discogs400-discogs-effnet-1.pb` (2 MB) - Classification genre +- `genre_discogs400-discogs-effnet-1.json` (15 KB) - Métadonnées genres +- `mtg_jamendo_moodtheme-discogs-effnet-1.pb` (2.6 MB) - Classification mood +- `mtg_jamendo_instrument-discogs-effnet-1.pb` (2.6 MB) - Classification instruments +- `mtg_jamendo_genre-discogs-effnet-1.pb` (2.7 MB) - Classification genre (alternatif) + +## Vérification des dépendances + +### Backend +```bash +cd backend +python check_dependencies.py +``` + +### Build Docker +```bash +# Backend +docker build -t audio-classifier-backend -f backend/Dockerfile . + +# Frontend +docker build -t audio-classifier-frontend -f frontend/Dockerfile . +``` + +## Notes de compatibilité + +- **Python**: 3.9 (requis pour essentia-tensorflow) +- **Architecture**: amd64 (meilleure compatibilité Essentia) +- **Node.js**: 20+ (pour Next.js 15) +- **PostgreSQL**: 16+ avec extension pgvector + +## Installation locale + +### Backend +```bash +cd backend +python -m venv venv +source venv/bin/activate # Windows: venv\Scripts\activate +pip install -r requirements.txt +pip install essentia-tensorflow +``` + +### Frontend +```bash +cd frontend +npm install +``` + +## Variables d'environnement requises + +Voir `.env.example` pour la liste complète des variables nécessaires. + +### Critiques +- `DATABASE_URL` - Connexion PostgreSQL +- `ADMIN_EMAIL` - Email admin +- `ADMIN_PASSWORD` - Mot de passe admin +- `JWT_SECRET_KEY` - Secret pour JWT (générer avec `openssl rand -hex 32`) diff --git a/backend/check_dependencies.py b/backend/check_dependencies.py new file mode 100644 index 0000000..1d84db7 --- /dev/null +++ b/backend/check_dependencies.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +"""Check all required dependencies are installed.""" +import sys + +def check_import(module_name, package_name=None): + """Try to import a module and report status.""" + package = package_name or module_name + try: + __import__(module_name) + print(f"✅ {package}") + return True + except ImportError as e: + print(f"❌ {package}: {e}") + return False + +def main(): + """Check all dependencies.""" + print("🔍 Checking Python dependencies...\n") + + dependencies = [ + # Web Framework + ("fastapi", "fastapi"), + ("uvicorn", "uvicorn"), + ("multipart", "python-multipart"), + + # Database + ("sqlalchemy", "sqlalchemy"), + ("psycopg2", "psycopg2-binary"), + ("pgvector.sqlalchemy", "pgvector"), + ("alembic", "alembic"), + + # Audio Processing + ("librosa", "librosa"), + ("soundfile", "soundfile"), + ("audioread", "audioread"), + ("mutagen", "mutagen"), + + # Scientific + ("numpy", "numpy"), + ("scipy", "scipy"), + + # Configuration + ("pydantic", "pydantic"), + ("pydantic_settings", "pydantic-settings"), + ("dotenv", "python-dotenv"), + ("email_validator", "email-validator"), + + # Authentication + ("jose", "python-jose"), + ("passlib", "passlib"), + + # Utilities + ("aiofiles", "aiofiles"), + ("httpx", "httpx"), + + # Essentia (optional) + ("essentia.standard", "essentia-tensorflow"), + ] + + all_ok = True + for module, package in dependencies: + if not check_import(module, package): + all_ok = False + + print("\n" + "="*50) + if all_ok: + print("✅ All dependencies installed!") + return 0 + else: + print("❌ Some dependencies are missing") + print("\nInstall missing dependencies with:") + print(" pip install -r requirements.txt") + return 1 + +if __name__ == "__main__": + sys.exit(main())