BloomBase — personal plant management app
Find a file
2026-05-31 21:09:58 +02:00
bloombase chore: rename PlantDB to BloomBase 2026-05-31 12:36:20 +02:00
caddy feat: add Caddy reverse proxy stack for bloombase.kerkman.io 2026-05-31 15:00:15 +02:00
docs/superpowers docs: add BloomBase redesign implementation plan 2026-05-31 21:09:58 +02:00
nginx fix: use \$http_host in nginx to preserve port for CSRF validation 2026-05-28 10:20:56 +02:00
plants feat: add area management — list, add, edit, delete locations 2026-05-31 15:17:36 +02:00
scripts fix: rewrite backup script — extract via Docker, rsync from host 2026-05-31 13:36:39 +02:00
.env.example feat: scaffold Django project with plants app 2026-05-27 19:40:58 +02:00
.gitignore feat: scaffold Django project with plants app 2026-05-27 19:40:58 +02:00
docker-compose.yml chore: rename PlantDB to BloomBase 2026-05-31 12:36:20 +02:00
Dockerfile feat: card scanning, OCR improvements, crop thumbnail, VPC enrichment 2026-05-29 21:54:59 +02:00
manage.py chore: rename PlantDB to BloomBase 2026-05-31 12:36:20 +02:00
pytest.ini feat: scaffold Django project with plants app 2026-05-27 19:40:58 +02:00
README.md docs: add Pl@ntNet to README (features, env vars, data sources) 2026-05-31 13:18:59 +02:00
requirements.txt feat: card scanning, OCR improvements, crop thumbnail, VPC enrichment 2026-05-29 21:54:59 +02:00

PlantDB

A personal plant management web app built with Django 5, Bootstrap 5, and HTMX.

Track your plants, identify them by photo, and get care info auto-filled from the Perenual and Pl@ntNet APIs.

Features

  • Plant identification — upload a photo; Pl@ntNet identifies it, shows top matches with reference images, pre-fills name and species, and saves the Pl@ntNet reference image as the plant thumbnail
  • Species search — search Perenual API by name; care data (watering, sunlight, pruning months) is auto-filled and cached locally
  • Plant list — filterable by name and location
  • 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 (112). 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-...
PLANTNET_API_KEY no 2b10... (get at my.plantnet.org)

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.
Pl@ntNet Active Plant identification from photos. Free tier: 500 req/day. Used for the identify-by-photo flow; reference image saved as plant thumbnail.
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.