--- 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.faiss` - `planclef_cache.pt` ## Installazione ```powershell python -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install --upgrade pip python -m pip install -r requirements.txt ``` ## Avvio server ```powershell 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 `Dockerfile` alla root - API FastAPI + frontend PWA serviti dallo stesso container - porta esposta: `7860` Passi: 1. Crea un nuovo Space su Hugging Face con SDK `Docker`. 2. Collega/pusha questa repository nello Space. 3. In `Settings -> Secrets` aggiungi almeno: - `OPENAI_API_KEY` - `GOOGLE_CLIENT_ID` (se vuoi login Google) 4. Opzionali in `Variables/Secrets`: - `OPENAI_MODEL` - `REQUIRE_GOOGLE_AUTH` (consigliato `1` in produzione) - `RAG_DB_PATH` (default `data/plant_rag`) - `PLANTS_SQLITE_PATH` (default `data/plants.db`) 5. 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-assets` se 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: ```powershell cd pwa-app npm install npm run dev ``` App locale: - PWA: `http://localhost:5173` Configurazione endpoint API (opzionale): - variabile `VITE_API_BASE` (default `http://localhost:8000`) - variabile `VITE_GOOGLE_CLIENT_ID` (obbligatoria per login Google nella PWA) Per produzione: ```powershell 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): ```powershell 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: ```powershell 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: ```powershell # 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_paths` nel RAG (URL immagini Wikipedia salvati nei metadati) - `data/rag_progress.json` (resume del processo) Migrazione una tantum da path locali a URL remoti: ```bash 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`; se `1/true/yes/on` richiede Bearer Google token) Esempio `.env`: ```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`): ```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=0` i token Bearer sono opzionali - con `REQUIRE_GOOGLE_AUTH=1` gli 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: ```powershell python build_plants_sqlite.py ``` Opzioni utili: ```powershell # 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_gg` - `annaffiatura_time` - `luce` - `temperatura` - `umidita` - `altezza_media` - `pulizia` - `terriccio` - `concimazione` - `prevenzione` 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: ```json { "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` (default `5`, min `1`, max `50`) - Body: `multipart/form-data` con `file=` Esempio: ```bash curl -X POST "http://localhost:8000/search?k=5" -F "file=@foto_pianta.jpg" ``` Esempio risposta: ```json { "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` (default `it`, usata nel fallback Wikipedia) Esempio: ```bash curl "http://localhost:8000/plant/Rosa%20canina?lang=it" ``` Esempio risposta: ```json { "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: ```bash curl "http://localhost:8000/plant/Rosa%20canina/profile" ``` Esempio risposta: ```json { "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: ```json { "plant_name": "Rosa canina", "question": "Ogni quanto devo annaffiarla in primavera?", "lang": "it" } ``` Esempio risposta: ```json { "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`, usa `python -m pip ...`. - Se Windows App Control blocca librerie native (`torch`, `faiss`), `/search` puo rispondere `503`. - Gli endpoint che usano OpenAI richiedono `OPENAI_API_KEY` valida. ## Struttura progetto (sintesi) ```text 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/ ```