Temp images uploaded during Pl@ntNet identification are now copied to PlantPhoto records when the plant is created in step 3. First image is auto-set as thumbnail. Temp files still deleted after transfer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| docs/superpowers | ||
| nginx | ||
| plantdb | ||
| plants | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| manage.py | ||
| pytest.ini | ||
| README.md | ||
| requirements.txt | ||
PlantDB
A personal plant management web app built with Django 5, Bootstrap 5, and HTMX.
Track your plants, log pruning activity, and get care info auto-filled from the Perenual species database.
Features
- Species search — search Perenual API by name; care data (watering, sunlight, pruning months) is auto-filled into the plant form and cached locally so the API is only called once per species
- Plant list — filterable by name, location, indoor/outdoor
- Plant detail — shows care info, pruning status, and pruning history
- Pruning log — log a pruning event with date and notes via HTMX partial update
- Pruning calendar — all plants grouped by urgency: overdue, due this month, due next month, later
- Dashboard — plant count, overdue pruning count, and attention list
Data model
Species — cached from Perenual API (common_name, scientific_name, watering,
sunlight, pruning_months, api_image_url, perenual_id)
Plant — your actual plant (name, location, is_indoor, pruning_months,
photo, notes, species FK)
PruningLog — pruning events (plant FK, pruned_on, notes)
Plant.pruning_months is a JSON list of integers (1–12). It defaults to the species value but can be overridden per plant.
Tech stack
| Layer | Library |
|---|---|
| Framework | Django 5.2 |
| Frontend | Bootstrap 5.3 + HTMX 1.9 |
| Image handling | Pillow |
| HTTP client | requests |
| Server | Gunicorn + Nginx |
| Database | SQLite |
Local development
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
Set PERENUAL_API_KEY in your environment to enable species search (free tier: 100 requests/day).
Run tests:
pytest
Deployment (Docker)
The production stack runs as two containers: web (Gunicorn) behind nginx.
# On the host — first time
cp .env.example .env # fill in SECRET_KEY, PERENUAL_API_KEY, ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS
docker compose up -d --build
After code changes:
# Sync files from dev machine
rsync -av --exclude='*.pyc' --exclude='__pycache__' . dockerhost:/home/stephan/stacks/plantdb/
# Rebuild
ssh dockerhost "cd /home/stephan/stacks/plantdb && docker compose up -d --build web"
Environment variables
| Variable | Required | Example |
|---|---|---|
SECRET_KEY |
yes | long random string |
DEBUG |
no | False |
ALLOWED_HOSTS |
yes | localhost,127.0.0.1,dockerhost |
CSRF_TRUSTED_ORIGINS |
yes (non-localhost) | http://dockerhost:8083 |
PERENUAL_API_KEY |
no | sk-... |
CSRF_TRUSTED_ORIGINS is required when accessing the app on a non-standard port or hostname — Django 5 rejects POSTs without it.
Volumes
| Volume | Purpose |
|---|---|
db |
SQLite database at /app/data/db.sqlite3 |
media |
User-uploaded plant photos |
static |
Collected static files |
Plant data sources — research notes
The app currently uses Perenual (free tier, 100 req/day) for species data. Other sources investigated:
| Source | Status | Verdict |
|---|---|---|
| Perenual | Active | Best structured care data (watering, sunlight, pruning months). Free tier sufficient for personal use; each species is cached after first lookup. |
| OpenFarm | Shut down April 2025 | Dead. GitHub repo is a Ruby/MongoDB app with no data dump. |
| Trefle | Active | Botanical taxonomy only — no care schedules. Not a replacement. |
| Wikipedia API | Active | Returns name, description, thumbnail. No structured care data. |
| Google Knowledge Panel | N/A | Has structured care data but scraping violates ToS and is technically brittle. |
Future opportunity
Google's plant Knowledge Panels aggregate care data (watering frequency, sunlight, pruning) from sources like The Sill, Bloomscape, Gardenia.net, and others. A curated, structured plant care dataset — particularly one covering common garden plants in NW Europe — does not currently exist as a clean, accessible API. This could be a commercial opportunity: either licensing a dataset or building a plant care API as a product.