AI-powered grocery shopping assistant for Lufa Farms
- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| lufa_assistant | ||
| skill | ||
| tests | ||
| .gitignore | ||
| ARCHITECTURE.md | ||
| COMPATIBILITY-PLAN.md | ||
| lufa | ||
| pyproject.toml | ||
| README.md | ||
| ROADMAP.md | ||
| uv.lock | ||
LUFA Assistant 🥬🤖
AI-powered grocery shopping for Lufa Farms
Status: ✅ Working
Demo
# Search products (no auth required)
$ uv run ./lufa search "organic eggs" -n 3
Product Size Price Supplier Avail
====================================================================================
Organic Free-Range Brown Eggs (12, large) 700g (each) $9.00 Nutrinor ✓
Organic Free-Range Brown Eggs (6, large) 350g (box) $5.00 Nutrinor ✓
Organic Omega-3 Eggs (6) each $4.75 Ferme Aux ✓
# Add to basket
$ uv run ./lufa add "cherry tomatoes"
✅ Added: Vitalion Cherry Tomatoes x1
# View basket
$ uv run ./lufa cart
🛒 Basket (3 items)
• Arugula x1 — $3.50
• Butter Chicken (mild) x1 — $20.75
• Vitalion Cherry Tomatoes x1 — $5.75
💰 Subtotal: $30.00
🚚 Delivery: $6.00
💳 Total: $38.52
Features
| Feature | Status | Description |
|---|---|---|
| 🔍 Search | ✅ | Fuzzy search products (EN/FR) |
| 📦 Browse | ✅ | Browse by category/subcategory |
| 🛒 Cart | ✅ | View/modify basket contents |
| ➕ Add | ✅ | Add products to basket |
| 📝 Local Cart | ✅ | Compose offline, sync later |
| 📋 Needs | ✅ | Household shopping needs list |
| ⭐ Preferences | ✅ | Favorites, substitutes, avoid lists |
| 📊 Formats | ✅ | Table, Telegram HTML, JSON |
| 💾 Session | ✅ | Persistent cookies |
| 🔐 Auth | ✅ | Import cookies from browser |
How It Works
Unlike Voilà (which blocks API access), LUFA has a relatively open API:
- Products: REST API
/superMarket/getAllProducts— no auth needed - Search: Client-side fuzzy matching (like LUFA's Fuse.js)
- Cart: API-based via
/superMarket/save— auth required - Basket Model: Weekly baskets + on-demand baskets supported
Installation
git clone https://github.com/echo931/lufa-assistant.git
cd lufa-assistant
uv sync
Alternative: pip (not recommended)
pip install -r requirements.txt
Quick Start
1. Search Products (no auth)
# Search
uv run ./lufa search "milk" -n 5
uv run ./lufa search "tomates" -f json # French works too
# Browse
uv run ./lufa categories
uv run ./lufa browse "Vegetables" -n 20
2. Authenticate
# Check status
uv run ./lufa status
# Interactive login (recommended)
uv run ./lufa login
# → Prompts for email/password
# → Saves session cookie only (password never stored)
# Logout / clear session
uv run ./lufa logout
Alternative: Import cookies from browser
uv run ./lufa import-cookies ~/lufa-cookies.json
To export cookies:
- Install a cookie export extension (EditThisCookie, Cookie-Editor)
- Log in to montreal.lufa.com
- Export cookies to JSON
- Import with the command above
3. Manage Basket
# View current basket
uv run ./lufa cart
uv run ./lufa basket-status
# Add items
uv run ./lufa add "organic eggs"
uv run ./lufa add "cherry tomatoes" -q 2 # Quantity 2
uv run ./lufa add "milk" -i 1 # Second search result
4. Local Cart (Offline Composition)
LUFA baskets are only open a few days before delivery. Use the local cart to build your list anytime:
# Add items throughout the week
uv run ./lufa local-add "eggs" -q 2
uv run ./lufa local-add "butter chicken"
uv run ./lufa local-add "organic milk"
# View local cart
uv run ./lufa local
# When basket opens, sync everything
uv run ./lufa local-sync --clear-after
5. Needs List (Household Shopping)
Track grocery needs from anyone in the household:
# Add needs
uv run ./lufa need "milk" -q 2
uv run ./lufa need "eggs" --who Emma
uv run ./lufa need "bread" --urgent
# View needs
uv run ./lufa needs
uv run ./lufa needs --compile # Format for shopping
# Transfer to local cart (uses preferences)
uv run ./lufa needs --to-local
# After shopping
uv run ./lufa needs --done # Mark all done
uv run ./lufa needs --clear-done # Remove done items
6. Product Preferences
Define favorites and substitutes:
# Set favorite
uv run ./lufa pref "milk" --favorite "2% Organic Milk"
# Add substitutes
uv run ./lufa pref "milk" --substitute "1% Organic Milk"
uv run ./lufa pref "milk" --substitute "Natrel 2%"
# Avoid certain products/brands
uv run ./lufa pref "milk" --avoid "Generic"
# View preferences
uv run ./lufa pref "milk" --show
uv run ./lufa prefs # List all
Preferences are used when transferring needs to local cart.
Output Formats
table(default): ASCII table for terminaltelegram: HTML formatted for Telegram botsjson: Raw JSON for programmatic use
uv run ./lufa search "apples" -f json
uv run ./lufa search "apples" -f telegram
Architecture
See ARCHITECTURE.md for technical details.
lufa_assistant/
├── cli.py # Command-line interface
├── client.py # HTTP client for LUFA API
├── search.py # Product search with fuzzy matching
├── cart.py # Basket operations
├── local_cart.py # Offline cart composition
├── needs.py # Household needs management
├── preferences.py # Product preferences
├── favorites.py # Favorites management
├── session.py # Cookie/session management
├── models.py # Data models
└── exceptions.py # Custom exceptions
Data files (~/.lufa-*):
├── ~/.lufa-session.json # Auth cookies
├── ~/.lufa-products-cache.json # Product catalog cache
├── ~/.lufa-local-cart.json # Local cart items
├── ~/.lufa-needs.json # Household needs
└── ~/.lufa-preferences.json # Product preferences
LUFA Basket Model
LUFA uses a unique basket system:
- Regular Baskets: Open ~3 days before your delivery date, close automatically
- On-Demand Baskets: Extra deliveries you can create anytime
- Minimum Order: $35 CAD (can't remove items below this)
- Pre-filled: LUFA suggests products (~$35 worth) that you can replace
This tool handles both basket types transparently.
Differences from Voilà Assistant
| Aspect | Voilà | LUFA |
|---|---|---|
| Product API | Blocked (scraping) | ✅ Open REST API |
| Cart API | Blocked (browser automation) | ✅ Works via API |
| Search | Server-side | Client-side fuzzy |
| Auth | Complex SSO (Gigya) | Simple PHP sessions |
| Basket Model | Traditional cart | Weekly subscription |
LUFA's more open architecture makes this project simpler and more reliable.
Limitations
- Montreal Area Only: LUFA delivers to specific regions
- Session Expiry: Cookies last ~30 days, then re-import
- Minimum $35: Can't have basket under this amount
- Weekly Model: Regular basket timing is fixed to your schedule
Development
# Run tests
pytest
# Type checking
mypy lufa_assistant/
# Format code
black lufa_assistant/
License
MIT — see LICENSE.
Built by Echo 🤖 — an AI assistant on thoth