# Capire la classe Interface

In questa sezione, daremo un'occhiata più da vicino alla classe `Interface` e scopriremo i
parametri principali che si usano per crearne una.

## Come creare una Interface

Si può notare che la classe `Interface` (_interfaccia_) ha 3 parametri necessari:

`Interface(fn, inputs, outputs, ...)`

Questi parametri sono:

  - `fn`: la funzione per le predizione chi viene utilizzata dall'interfaccia di Gradio. Questa funzione può accettare uno o più parametri e restituire uno o più valori
  - `inputs`: il/i tipo/i dei componenti in input. Gradio fornisce molti componenti predefiniti, come `"image"`(_immagine_) o `"mic"`(_microfono_). 
  - `outputs`: il/i tipo/i dei componenti in output. Anche in questo caso, Gradio fornisce molti componenti predefiniti, come `"image"` o `"label"`. 

Per un elenco completo dei componenti, [consultare la documentazione di Gradio](https://gradio.app/docs). Ogni componente predefinito può essere personalizzato istanziando la classe corrispondente al componente.

Ad esempio, come abbiamo visto nella [sezione precedente](/course/chapter9/2),
invece di passare `"textbox"` al parametro `inputs`, si può passare un componente `Textbox(lines=7, label="Prompt")` per creare una casella di testo con 7 righe e un'etichetta.

Diamo un'occhiata a un altro esempio, questa volta con un componente `Audio`.

## Un semplice esempio con l'audio

Come detto in precedenza, Gradio fornisce molti input e output differenti.
Costruiamo perciò una `Interface` che funziona con l'audio.

In questo esempio, svilupperemo una funzione da audio ad audio che prende un
file audio e semplicemente lo inverte.

Per l'input utilizzeremo il componente `Audio`. Quando si usa il componente `Audio`,
si può specificare se si vuole che la `source` (_sorgente_) dell'audio sia un file
caricato dall'utente o un microfono con cui l'utente può registrare la propria voce. In questo caso,
impostiamo `"microphone"`. Per divertimento, aggiungeremo un'etichetta al nostro `Audio` che dice
"Speak here..." (_"Parla qui..."_). 

Inoltre, vorremmo ricevere l'audio come un numpy array, in modo da poterlo facilmente
"invertire". Impostiamo quindi il `"type"` come `"numpy"`, che passa i dati in input
come una tupla di (`sample_rate`, `data`) alla nostra funzione.

Utilizzeremo anche il componente di output `Audio`, il quale può convertire automaticamente
una tupla formata da una frequenza di campionamento e un numpy array di dati in un file audio riproducibile.
In questo caso, non abbiamo bisogno di fare alcuna personalizzazione, quindi useremo la stringa
`"audio"`.

```py
import numpy as np
import gradio as gr

def reverse_audio(audio):
    sr, data = audio
    reversed_audio = (sr, np.flipud(data))
    return reversed_audio

mic = gr.Audio(source="microphone", type="numpy", label="Speak here...")
gr.Interface(reverse_audio, mic, "audio").launch()
```

Il codice precedente produrrà un'interfaccia come quella qui sotto (se il tuo browser non
chiede il premesso per usare il microfono, apri il demo in una tab diversa.)

A questo punto potresti registrare la tua voce e di sentirti parlare al contrario - spaventoso 👻!

## Lavorare con più input e output

Supponiamo di avere una funzione più complicata, con più input e output.
Nell'esempio seguente, abbiamo una funzione che richiede un elenco a tendina, il valore di uno slider e un numero,
e restituisce il campione audio di una nota musicale.

Osserva come si passa un elenco di componenti di input e di output,
e vedi se riesci a seguire quello che succede.

La questione fondamentale è che quando si passa:
* un elenco di componenti di input, ogni componente corrisponde in ordine a un parametro.
* un elenco di componenti di output, ogni componente corrisponde a un valore restituito.

Lo snippet di codice qui sotto mostra come tre componenti di input si abbinano ai tre argomenti della funzione `generate_tone()`:

```py
import numpy as np
import gradio as gr

notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]

def generate_tone(note, octave, duration):
    sr = 48000
    a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9)
    frequency = a4_freq * 2 ** (tones_from_a4 / 12)
    duration = int(duration)
    audio = np.linspace(0, duration, duration * sr)
    audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16)
    return (sr, audio)

gr.Interface(
    generate_tone,
    [
        gr.Dropdown(notes, type="index"),
        gr.Slider(minimum=4, maximum=6, step=1),
        gr.Textbox(type="number", value=1, label="Duration in seconds"),
    ],
    "audio",
).launch()
```

### Il metodo `launch()`

Per ora, abbiamo utilizzato il metodo `launch()` per avviare l'interfaccia, ma
non abbiamo discusso realmente cosa fa.

Di default, il metodo `launch()` avvia la demo in un web server che
che viene eseguito in locale. Se si esegue il codice in un Jupyter o Colab notebook, 
Gradio incorporerà l'interfaccia grafica della demo nel notebook, così da poterla usare facilmente.

È possibile modificare il comportamento di `launch()` attraverso diversi parametri:

  - `inline` - per visualizzare l'interfaccia _inline_ sui notebook di Python.
  - `inbrowser` - per avviare automaticamente l'interfaccia in una nuova scheda del browser di default.
  - `share` - per create un link pubblico per l'interfaccia da condividere dal proprio computer. Un po' come un link di Google Drive!

Il parametro `share` sarà trattato in modo molto più dettagliato nella prossima sezione!

## ✏️ Mettiamolo in pratica!

Costruiamo un'interfaccia che permetta di provare un modello di **riconoscimento vocale**.
Per renderlo interessante, accetteremo un input *qualisiasi* tra un microfono o un file caricato.

Come al solito, caricheremo il nostro modello di riconoscimento vocale usando la funzione `pipeline()` da 🤗 Transformers.
Se si ha bisogno di un ripasso veloce, si può tornare a [quella sezione nel Capitolo 1](/course/chapter1/3).     Quindi, implementeremo una funzione `transcribe_audio()` che elabora l'audio e restituisce la sua trascrizione. Infine, avvolgeremo questa funzione in una `Interface` con i componenti `Audio` per gli input e solo testo per l'output. Il codice completo per questa applicazione è il seguente:

```py
from transformers import pipeline
import gradio as gr

model = pipeline("automatic-speech-recognition")

def transcribe_audio(mic=None, file=None):
    if mic is not None:
        audio = mic
    elif file is not None:
        audio = file
    else:
        return "You must either provide a mic recording or a file"
    transcription = model(audio)["text"]
    return transcription

gr.Interface(
    fn=transcribe_audio,
    inputs=[
        gr.Audio(source="microphone", type="filepath", optional=True),
        gr.Audio(source="upload", type="filepath", optional=True),
    ],
    outputs="text",
).launch()
```

Se il tuo browser non ti chiede i permessi per il microfono, apri la demo in una scheda separata.

Ecco fatto! Ora è possibile utilizzare questa interfaccia per trascrivere l'audio. Si osservi che
passando il parametro `optional` come `True`, si permette all'utente di
fornire o un microfono o un file audio (o nessuno dei due, ma questo restituirà un messaggio di errore).

Continua a leggere per scoprire come condividere la tua interfaccia con gli altri!

