Pick-a-Recipe is a Python-based application that extracts recipes from social media videos (TikTok, YouTube, Instagram, etc.) and uploads them to self-hosted recipe managers like Tandoor and Mealie. The application uses AI for transcription, visual text extraction, and recipe generation.
- Python 3.11+ - Primary language
- Flask - Web framework for the UI
- SQLite - Database for configuration and history
- Docker - Containerization support
- yt-dlp - Video downloading from multiple platforms
- faster-whisper - Audio transcription using Whisper AI
- openai - OpenAI GPT API integration
- google-genai - Google Gemini API integration
- flask-socketio - Real-time web communication
- eventlet - Async server support
pick-a-recipe/
├── main.py # CLI entry point
├── chef.py # AI recipe generation core
├── config.py # Configuration management (SQLite-based)
├── video_downloader.py # Video downloading (yt-dlp wrapper)
├── transcriber.py # Audio transcription + visual text extraction
├── image_extractor.py # Dish image extraction from video
├── mealie.py # Mealie recipe manager integration
├── tandoor.py # Tandoor recipe manager integration
├── recipe_exporter.py # Recipe export utilities
├── helpers.py # Utility functions and AI prompts
├── llm_providers/ # Modular LLM provider implementations
│ ├── base.py # Abstract base class
│ ├── openai.py # OpenAI GPT integration
│ └── gemini.py # Google Gemini integration
├── ui/ # Flask web application
│ ├── app.py # Main Flask app with authentication
│ ├── database.py # SQLite database operations
│ ├── job_manager.py # Background job processing
│ ├── templates/ # HTML templates
│ └── static/ # CSS, JS, and PWA assets
├── Dockerfile # Container configuration
├── docker-compose.yml # Docker Compose setup
├── docker-compose.srv2.yml
├── build-and-push.sh # Publish pickeld/pick-a-recipe to Docker Hub
├── portainer/
│ ├── stack.yml # srv2 / Portainer production stack
│ └── stack.env
├── scripts/
│ ├── portainer-migrate.sh
│ └── portainer-deploy.sh
└── requirements.txt # Python dependencies
- Video Download (
video_downloader.py) - Uses yt-dlp to download videos from social platforms - Audio Transcription (
transcriber.py) - Extracts and transcribes audio using Whisper - Visual Text Extraction (
transcriber.py) - Uses vision-capable LLMs to extract on-screen text - Image Extraction (
image_extractor.py) - Extracts best dish image from video frames - Recipe Generation (
chef.py) - Uses LLMs to create structured recipe from combined data - Recipe Upload (
mealie.py/tandoor.py) - Uploads to recipe manager APIs
- Flask Backend with SocketIO for real-time updates
- SQLite Database for user authentication, configuration, and job history
- Background Job Processing with progress tracking
- PWA Support for mobile app installation and sharing integration
- Abstract Base Class (
llm_providers/base.py) for consistent interface - OpenAI Provider (
llm_providers/openai.py) - GPT models - Gemini Provider (
llm_providers/gemini.py) - Google Gemini models - Configurable Selection via web UI settings
- 🎥 Multi-platform Video Support - TikTok, YouTube, Instagram, Facebook, Twitter/X
- 🎙️ Audio Transcription - Automatic language detection with Whisper AI
- 👁️ Visual Text Extraction - OCR-like capabilities using vision LLMs
- 🤖 AI Recipe Generation - Structured recipe creation with ingredients and instructions
- 🍽️ Nutrition Estimation - Automatic serving size and nutrition calculation
- 🖼️ Image Extraction - Automatic dish image extraction with manual selection
- 🌐 Web UI - Flask-based interface with real-time progress
- 🔐 Authentication - User login with configurable credentials
- ⚙️ Settings Management - Web-based configuration for all options
- 📱 PWA Support - Install as mobile app, direct sharing from social apps
- 🐳 Docker Support - Easy deployment via Docker Hub
- 🔗 Recipe Manager Support - Tandoor and Mealie integration
- 📊 Job History - Track processing jobs with status and results
- 🔄 Background Processing - Non-blocking job execution
- 💾 Caching - Transcription and visual text caching to avoid re-processing
Quick Start:
docker run -d \
--name pick-a-recipe \
-p 5006:5006 \
-e FLASK_SECRET_KEY="your-secure-secret-key" \
-v pick-a-recipe-data:/app/data \
pickeld/pick-a-recipe:latestDocker Compose:
# Use the provided docker-compose.yml
docker-compose up -dPrerequisites:
# Install system dependencies
sudo apt-get install ffmpeg # Ubuntu/Debian
brew install ffmpeg # macOSSetup:
# Clone and setup
git clone https://github.com/pickeld/pick-a-recipe.git
cd pick-a-recipe
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run web UI
python ui/app.py
# Or run CLI
python main.py "https://www.tiktok.com/@user/video/123"Access:
- Web UI:
http://localhost:5006 - Default credentials:
admin/admin123
- All settings stored in SQLite database (
data/pick-a-recipe.db) - Web UI provides settings page for configuration
- Fallback to sensible defaults if database unavailable
- LLM Provider: OpenAI or Google Gemini
- API Keys: OpenAI or Gemini authentication
- Language Settings: Recipe output language and transcription target
- Recipe Manager: Tandoor or Mealie integration
- Processing Options: Whisper model size, confirmation workflows
- Single Responsibility: Each module has a clear, focused purpose
- Configuration Abstraction: Database-backed config with property-based access
- Provider Pattern: Pluggable LLM providers with consistent interface
- Caching Strategy: File-based caching for expensive operations (transcription, visual text)
- Graceful Degradation: Visual text extraction failures don't break the pipeline
- Logging: Structured logging throughout with step-based progress
- Validation: Input validation and API error handling
- Caching: Transcription and visual text cached by language and video ID
- Background Jobs: Non-blocking processing via job manager
- Progressive Loading: Real-time updates via WebSockets
- Session Management: Secure Flask sessions with persistent secret keys
- File Permissions: Restricted permissions on secret key files
- Input Validation: URL validation and sanitization
- API Key Storage: Encrypted storage in SQLite database
- New LLM providers can be added by extending
llm_providers/base.py - Recipe manager integrations follow consistent pattern (
mealie.py,tandoor.py) - Configuration system easily supports new settings
- CLI supports
--no-uploadflag for testing without recipe manager - Default test URL provided in argument parser
- Caching reduces costs during development iterations
- Docker Hub image:
pickeld/pick-a-recipe - Publish updates:
./build-and-push.sh latest(requiresdocker login -u pickeld) - srv2 production:
./scripts/portainer-migrate.sh(pullspickeld/pick-a-recipe:latest) - Portainer API deploy:
./scripts/portainer-deploy.sh --pull - Volume mounts preserve data and configuration (
pick-a-recipe-dataor legacysocial_recipe_social-recipeson srv2) - Environment variable overrides for deployment flexibility
This codebase represents a well-structured, production-ready application with clear separation of concerns, comprehensive error handling, and thoughtful user experience design.