Spaces:
Sleeping
title: Clorofilla
sdk: docker
app_port: 7860
colorFrom: green
colorTo: blue
pinned: false
Clorofilla
API FastAPI + UI web per:
- ricerca specie vegetali simili da immagine (OpenCLIP + FAISS)
- schede pianta con riassunto AI basato su knowledge base RAG
- chatbot di cura botanica con contesto da RAG (fallback Wikipedia)
Requisiti
- Python 3.10+
- Ambiente virtuale consigliato (
.venv) - Dati PlantCLEF in
data/:planclef.faissplanclef_cache.pt
Installazione
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
Avvio server
python -m uvicorn api:app --reload
Server locale:
- API base:
http://localhost:8000 - UI:
http://localhost:8000/ - Swagger:
http://localhost:8000/docs
Deploy su Hugging Face Spaces (Docker)
Questa repo e pronta per Spaces in modalita Docker:
- file
Dockerfilealla root - API FastAPI + frontend PWA serviti dallo stesso container
- porta esposta:
7860
Passi:
- Crea un nuovo Space su Hugging Face con SDK
Docker. - Collega/pusha questa repository nello Space.
- In
Settings -> Secretsaggiungi almeno:
OPENAI_API_KEYGOOGLE_CLIENT_ID(se vuoi login Google)
- Opzionali in
Variables/Secrets:
OPENAI_MODELREQUIRE_GOOGLE_AUTH(consigliato1in produzione)RAG_DB_PATH(defaultdata/plant_rag)PLANTS_SQLITE_PATH(defaultdata/plants.db)
- Avvia il build dello Space.
Note operative:
- In Spaces il frontend viene compilato nel Docker build e servito dalla API.
- Se usi Google login, configura gli URI autorizzati nel progetto Google OAuth con il dominio dello Space (https://-.hf.space).
- Per usare ricerca immagini, tutti gli artifact FAISS/cache e il database ChromaDB vengono scaricati automaticamente dal dataset Hugging Face
AChierici84/GreenAssistent-assetsse non sono gia presenti nei path configurati.
Frontend React PWA
E disponibile una PWA React in pwa-app/ con flusso completo:
- upload immagine e riconoscimento specie (
/search) - apertura scheda pianta con estrazioni (
/plant/{name}+/plant/{name}/profile) - domanda sulla cura (
/chat/plant-care) - salvataggio "Le tue piante" con nome personalizzato (
/user/plants)
Avvio in sviluppo:
cd pwa-app
npm install
npm run dev
App locale:
- PWA:
http://localhost:5173
Configurazione endpoint API (opzionale):
- variabile
VITE_API_BASE(defaulthttp://localhost:8000) - variabile
VITE_GOOGLE_CLIENT_ID(obbligatoria per login Google nella PWA)
Per produzione:
cd pwa-app
npm run build
npm run preview
Build della knowledge base RAG (opzionale ma consigliato)
Per costruire/aggiornare il database piante locale (ChromaDB + immagini):
python build_plant_rag.py
Per recuperare solo le specie non indicizzate (indexed=0 nel DB SQLite), cercare Wikipedia in piu lingue e tradurre in italiano prima dell'upsert nella RAG:
python build_plant_rag.py --from-sqlite-indexed-zero --langs it,en,fr,es,de,pt --translate-non-italian
Opzioni utili per il build RAG:
# usa un DB SQLite specifico per leggere le specie indexed=0
python build_plant_rag.py --from-sqlite-indexed-zero --sqlite-path data/plants.db
# disattiva traduzione (mantiene il testo nella lingua trovata)
python build_plant_rag.py --no-translate-non-italian
# cambia modello OpenAI per traduzione
python build_plant_rag.py --translation-model gpt-4o-mini
Output principali:
data/plant_rag/(database vettoriale persistente)image_pathsnel RAG (URL immagini Wikipedia salvati nei metadati)data/rag_progress.json(resume del processo)
Migrazione una tantum da path locali a URL remoti:
python migrate_rag_image_paths_to_urls.py --dry-run --limit 10
python migrate_rag_image_paths_to_urls.py
Configurazione (variabili ambiente)
Puoi impostare le variabili in .env (caricato automaticamente) o via shell.
PLANCLEF_INDEX_PATH(default:data/planclef.faiss)PLANCLEF_CACHE_PATH(default:data/planclef_cache.pt)PLANCLEF_MODEL_NAME(default:ViT-B-32)LEAFSNAP_INDEX_PATH(default:data/leafsnap.faiss, oppure/data/greenassistent-assets/...su Spaces con persistent storage)LEAFSNAP_CACHE_PATH(default:data/leafsnap_cache.pt, oppure/data/greenassistent-assets/...su Spaces con persistent storage)HF_ASSETS_DATASET_REPO(default:AChierici84/GreenAssistent-assets)RAG_DB_PATH(default:data/plant_rag)PLANTS_SQLITE_PATH(default:data/plants.db)USER_PLANTS_SQLITE_PATH(default:data/user_plants.db)WIKI_USER_AGENT(default:clorofilla/1.0 (contact: local-dev))OPENAI_API_KEY(obbligatoria per/plant/{name}e/chat/plant-care)OPENAI_MODEL(default:gpt-4o-mini)GOOGLE_CLIENT_ID(uno o piu client id Google OAuth separati da virgola)REQUIRE_GOOGLE_AUTH(default:0; se1/true/yes/onrichiede Bearer Google token)
Esempio .env:
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-mini
PLANCLEF_INDEX_PATH=data/planclef.faiss
PLANCLEF_CACHE_PATH=data/planclef_cache.pt
PLANCLEF_MODEL_NAME=ViT-B-32
RAG_DB_PATH=data/plant_rag
PLANTS_SQLITE_PATH=data/plants.db
USER_PLANTS_SQLITE_PATH=data/user_plants.db
WIKI_USER_AGENT=clorofilla/1.0 (contact: local-dev)
GOOGLE_CLIENT_ID=xxxxxxxxxxxx-abcdefg.apps.googleusercontent.com
REQUIRE_GOOGLE_AUTH=0
Variabili .env lato PWA (pwa-app/.env):
VITE_API_BASE=http://localhost:8000
VITE_GOOGLE_CLIENT_ID=xxxxxxxxxxxx-abcdefg.apps.googleusercontent.com
Nota autenticazione:
- endpoint login:
POST /auth/google(valida l'id_token Google) - con
REQUIRE_GOOGLE_AUTH=0i token Bearer sono opzionali - con
REQUIRE_GOOGLE_AUTH=1gli endpoint principali (/search,/plant/*,/chat/plant-care,/species/*) richiedono login - endpoint sempre autenticati:
POST /user/plants,GET /user/plants
Build database SQLite piante
Per creare un database SQLite con tabella plants, campo indexed (0/1) e campi di cura estratti da RAG + OpenAI:
python build_plants_sqlite.py
Opzioni utili:
# solo prime 20 specie (test rapido)
python build_plants_sqlite.py --limit 20
# ricalcola anche specie gia arricchite
python build_plants_sqlite.py --force-refresh
# disattiva fallback OpenAI generico per campi mancanti
python build_plants_sqlite.py --no-generic-fallback
# disattiva integrazione fonti esterne (RHS, Missouri, EPPO)
python build_plants_sqlite.py --no-external-sources
Campi valorizzati quando indexed=1:
annaffiatura_ggannaffiatura_timelucetemperaturaumiditaaltezza_mediapuliziaterriccioconcimazioneprevenzione
Se OPENAI_API_KEY non e impostata, lo script compila comunque indexed e lascia i campi descrittivi a NULL.
Con --generic-fallback (attivo di default), se alcuni campi restano NULL dopo estrazione da RAG,
lo script esegue una seconda chiamata OpenAI basata su conoscenza generale botanica per tentare di completarli.
Con --external-sources (attivo di default), lo script prova anche a integrare evidenze da:
- RHS (cura pratica)
- Missouri Botanical Garden (cura pratica)
- EPPO (prevenzione fitosanitaria)
Infine usa OpenAI come normalizzatore finale dei dati aggregati (RAG + fonti esterne) verso il JSON strutturato del DB.
Endpoint API
1) Health
- Metodo:
GET - Path:
/health
Esempio risposta:
{
"status": "ok",
"model": "ViT-B-32",
"search_backend_ready": true
}
2) Stato backend ricerca immagine
- Metodo:
GET - Path:
/search/status
Restituisce diagnostica modulo/file (torch, faiss, open_clip, presenza index/cache).
3) Ricerca immagini simili
- Metodo:
POST - Path:
/search - Query:
k(default5, min1, max50)
- Body:
multipart/form-dataconfile=<immagine>
Esempio:
curl -X POST "http://localhost:8000/search?k=5" -F "file=@foto_pianta.jpg"
Esempio risposta:
{
"results": [
{"species": "Rosa canina", "score": 0.9212},
{"species": "Prunus spinosa", "score": 0.8731}
]
}
4) Scheda pianta (RAG + OpenAI, fallback Wikipedia)
- Metodo:
GET - Path:
/plant/{name} - Query:
lang(defaultit, usata nel fallback Wikipedia)
Esempio:
curl "http://localhost:8000/plant/Rosa%20canina?lang=it"
Esempio risposta:
{
"title": "Rosa canina",
"common_name": "Rosa canina",
"markdown": "# Rosa canina\n...",
"summary": "...",
"images": ["/images/images/rosa_canina/xxx.jpg"],
"source": "rag"
}
5) Profilo strutturato da plants.db
- Metodo:
GET - Path:
/plant/{name}/profile
Restituisce i campi salvati nel database SQLite plants.db per la specie richiesta.
Esempio:
curl "http://localhost:8000/plant/Rosa%20canina/profile"
Esempio risposta:
{
"species_name": "Rosa canina",
"indexed": true,
"annaffiatura_gg": 4,
"annaffiatura_time": "mattino",
"luce": "piena luce",
"temperatura": "temperata",
"umidita": "media",
"altezza_media": "2-3 m",
"pulizia": "rimuovere foglie secche",
"terriccio": "ben drenato",
"concimazione": "primavera",
"prevenzione": "controllare afidi e oidio",
"updated_at": "2026-04-29T10:03:16.214041+00:00"
}
6) Chatbot cura pianta
- Metodo:
POST - Path:
/chat/plant-care - Body JSON:
{
"plant_name": "Rosa canina",
"question": "Ogni quanto devo annaffiarla in primavera?",
"lang": "it"
}
Esempio risposta:
{
"plant": "Rosa canina",
"common_name": "",
"question": "Ogni quanto devo annaffiarla in primavera?",
"answer": "...",
"source": "RAG",
"source_url": "",
"model": "gpt-4o-mini"
}
6) Servizio immagini locali
- Metodo:
GET - Path:
/images/{full_path}
Serve le immagini presenti sotto data/images.
Nota: /plant/{name} accetta anche URL remoti salvati in image_paths; il servizio locale resta utile solo se mantieni una cache su disco.
UI
La UI servita da / include tre tab:
- Ricerca per immagine
- Info su una pianta
- Chatbot cura
Note operative
- Al primo avvio il caricamento del modello puo richiedere tempo.
- Se policy aziendali bloccano
pip.exe, usapython -m pip .... - Se Windows App Control blocca librerie native (
torch,faiss),/searchpuo rispondere503. - Gli endpoint che usano OpenAI richiedono
OPENAI_API_KEYvalida.
Struttura progetto (sintesi)
ai-green-assistent/
api.py
build_plant_rag.py
plentclef.py
ui.html
requirements.txt
unique_species_labels.csv
data/
planclef.faiss
planclef_cache.pt
plant_rag/
images/