MODULO 07 ยท CLASSE QUINTA

Integrazione Web (JavaScript)

Una pagina web che carica un'immagine e mostra la classificazione restituita dall'API Python

๐ŸŽฏ Obiettivi del modulo

1. Il flusso completo

Chiudiamo il cerchio del triennio: la pagina HTML/JS (frontend) invia un'immagine al server FastAPI (backend, Modulo 06), che la passa a un modello giร  addestrato e restituisce la classe prevista.

  1. L'utente seleziona un'immagine nella pagina web
  2. JavaScript invia il file al backend con una richiesta fetch
  3. Il server Python riceve l'immagine, la passa al modello, restituisce un JSON
  4. JavaScript legge il JSON e aggiorna la pagina con il risultato

2. Backend: endpoint che accetta un'immagine

from fastapi import FastAPI, File, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from PIL import Image
import numpy as np
import io
import pickle

app = FastAPI()

# Permette alla pagina web (origine diversa) di chiamare l'API
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

with open("modello_immagini.pkl", "rb") as f:
    modello = pickle.load(f)

@app.post("/classifica")
async def classifica_immagine(file: UploadFile = File(...)):
    contenuto = await file.read()
    img = Image.open(io.BytesIO(contenuto)).convert("L").resize((28, 28))
    array = np.array(img).reshape(1, -1) / 255.0

    classe = modello.predict(array)[0]
    return {"classe_prevista": str(classe)}
CORS: quando la pagina HTML e l'API girano su porte/domini diversi, il browser blocca la richiesta per sicurezza a meno che il server non lo permetta esplicitamente โ€” da qui il CORSMiddleware.

3. Frontend: pagina HTML con upload e JavaScript

<!DOCTYPE html>
<html lang="it">
<body>
  <h1>Classificatore di Immagini</h1>
  <input type="file" id="inputImmagine" accept="image/*">
  <button onclick="classifica()">Classifica</button>
  <p id="risultato"></p>

  <script>
    async function classifica() {
      const input = document.getElementById("inputImmagine");
      const risultatoEl = document.getElementById("risultato");

      if (!input.files.length) {
        risultatoEl.textContent = "Seleziona prima un'immagine.";
        return;
      }

      const formData = new FormData();
      formData.append("file", input.files[0]);

      risultatoEl.textContent = "Classificazione in corso...";

      try {
        const risposta = await fetch("http://127.0.0.1:8000/classifica", {
          method: "POST",
          body: formData
        });
        const dati = await risposta.json();
        risultatoEl.textContent = "Classe prevista: " + dati.classe_prevista;
      } catch (errore) {
        risultatoEl.textContent = "Errore: " + errore;
      }
    }
  </script>
</body>
</html>

Nota come fetch con FormData replichi, a livello browser, lo stesso schema richiesta/risposta visto con i socket in Quarta โ€” solo che ora client e server "parlano" HTTP e JSON in modo standard.

4. Verso il Progetto Finale

Questo modulo chiude il percorso tecnico del triennio: dati (Terza) โ†’ modello (Quarta/Quinta) โ†’ servizio di rete (socket, Quarta) โ†’ API REST (Quinta) โ†’ interfaccia web (questo modulo). Il Progetto Finale AI mette insieme tutti questi pezzi in un sistema unico, con MySQL a persistere dati e previsioni.

๐Ÿ’ช Esercizi

  1. Facile: crea una pagina HTML con un campo numerico che chiama l'API di regressione del Modulo 06 tramite fetch e mostra il risultato.
  2. Medio: realizza l'upload di un'immagine come nell'esempio, gestendo anche il caso in cui il server non รจ raggiungibile (messaggio d'errore chiaro per l'utente).
  3. Difficile: aggiungi un'anteprima dell'immagine caricata prima dell'invio e una barra di caricamento durante l'attesa della risposta dal server.

๐Ÿ“Œ Riepilogo

fetch() permette a una pagina JavaScript di chiamare un'API Python, inviando dati (anche file) e ricevendo una risposta JSON da mostrare dinamicamente. Con CORS abilitato sul backend, frontend e backend possono comunicare anche su origini diverse โ€” lo schema base di ogni applicazione web moderna basata su IA.

โ† Modulo 06: API RESTful Torna all'indice del corso โ†’