Covers local dev, Docker deployment, env vars, data model, and a summary of plant data sources investigated (Perenual, OpenFarm, Trefle, Wikipedia, Google) including the commercial data opportunity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
112 lines
4.1 KiB
Markdown
112 lines
4.1 KiB
Markdown
# 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
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
pytest
|
||
```
|
||
|
||
## Deployment (Docker)
|
||
|
||
The production stack runs as two containers: `web` (Gunicorn) behind `nginx`.
|
||
|
||
```bash
|
||
# 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:
|
||
|
||
```bash
|
||
# 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.
|