FastAPI: framework API per servire prodotti di dati di machine learning

Mar 22 2023
Al giorno d'oggi la maggior parte dei modelli di machine learning viene offerta in produzione come servizio. Questo metodo disaccoppia le applicazioni client dai modelli di machine learning tramite l'API (Application Programming Interface).
Foto di Chris Ried su Unsplash

Al giorno d'oggi la maggior parte dei modelli di machine learning viene offerta in produzione come servizio. Questo metodo disaccoppia le applicazioni client dai modelli di machine learning tramite l'API (Application Programming Interface).

In questo articolo, ti illustrerò il concetto di API, le funzionalità rivoluzionarie di FastAPI e servirò il nostro prodotto di dati di machine learning con FastAPI.

Cos'è un'API?

Un'interfaccia di programmazione dell'applicazione ( API ) è un'interfaccia software per la comunicazione tra due o più applicazioni.

Il modo più semplice per capire cos'è un'API è pensare a te stesso in un ristorante. Entri nel ristorante, trovi il tuo tavolo e ricevi un menu. Sul menu ci sono nomi, descrizioni e costi del cibo. Scegli la tua combinazione e vuoi dare un ordine. Ma come verrà consegnata allo chef la tua richiesta? Lo chef non può venire in sala da pranzo e tu non puoi andare in cucina. Hai bisogno di qualcuno che riceva la tua richiesta e la consegni in cucina e più tardi, quando il pasto è pronto, lo porti al tuo tavolo. Sì, hai bisogno di un cameriere o di una cameriera!

La stessa analogia vale per le applicazioni. Per fare in modo che le applicazioni parlino tra loro o ricevano le loro richieste e pubblichino i loro output, le API fungono da intermediario.

Esempi di API

Google Maps: Google Maps serve varie API nell'applicazione. Quando cerchi una città, un'area o un quartiere, popola il tempo, la qualità dell'aria e anche durante il periodo covid i risultati dell'ultima infezione. Allo stesso modo, quando cerchi un posto dove mangiare, Google Maps ti mostra i ristoranti, i caffè, i loro menu, gli orari di apertura e anche se sono disponibili opzioni di prenotazione online tramite applicazioni di terze parti.

Applicazioni di viaggio: Booking.com, Trivago, Expedia e altri ti offrono esperienze di viaggio end-to-end in questi giorni. Quando controlli le loro applicazioni puoi prenotare un hotel, acquistare biglietti aerei, noleggiare un'auto o effettuare una prenotazione a un evento di degustazione di vini. Nessuno di questi elementi è direttamente posseduto e gestito da queste società. Ricevono la tua richiesta e si collegano alle altre applicazioni che forniscono queste informazioni.

API veloce

FastAPI è un framework Web per lo sviluppo di API RESTful in Python. FastAPI sta aumentando la sua base di utenti ogni giorno. Non solo gli ingegneri del software, ma anche i data scientist, gli ingegneri dell'apprendimento automatico e i data engineer hanno iniziato a utilizzare FastAPI. Il movimento è stato rivoluzionario che ha spinto tutti i data people a migrare da Flask e Django a FastAPI in un breve lasso di tempo.

Screenshot da — https://fastapi.tiangolo.com/

Funzionalità GAME Changer di FastAPI

Richieste sincrone e asincrone

Prima di addentrarci nelle definizioni tecniche torniamo al nostro esempio di ristorante.

Dai il tuo ordine al cameriere e lui ti dice che c'è solo un cuoco in cucina e ha già 5 richieste in coda ! Inizi ad aspettare che il tuo ordine venga consegnato. Dopo 30 minuti con le scuse arriva il tuo pasto. Impari che una sola persona, quanto può essere veloce, non può gestire 10 tavoli contemporaneamente. Questa è una richiesta sincrona.

La prossima volta vuoi provare un altro ristorante. Prima di dare il tuo ordine, chiedi al cameriere quanti cuochi ha. Il cameriere ride di te e ti dice che “Abbiamo i 5 cuochi in cucina e stanno aspettando di servirti, signore. Non siamo dilettanti!” Dai il tuo ordine e 10 minuti dopo ricevi la tua richiesta. Ti guardi intorno e vedi che vengono serviti anche altri tavoli. Questa è una richiesta asincrona.

Una chiamata API sincrona è un modello di progettazione in cui il sito di chiamata viene bloccato durante l'attesa del completamento del codice chiamato. Con una chiamata API asincrona, il sito di chiamata non viene bloccato durante l'attesa del completamento del codice chiamato, ma al thread chiamante viene notificato l'arrivo della risposta.

In condizioni di carico più intenso, può essere più efficiente inviare più chiamate asincrone e controllare periodicamente lo stato piuttosto che attendere il completamento di ogni chiamata prima di inviare quella successiva.

from fastapi import FastAPI

app = FastAPI()

async def get_restaurant_working_hours():
    # some operations
    pass


@app.get("/")
async def get_resturant_reservation_details():
    results = await restaurant_working_hours() # waits for the defined function
    # some operations 
    
    return results

FastAPI supporta le convalide di stringhe e parametri numerici.

Esempio di convalida della stringa

Nell'esempio seguente, ho aggiunto un vincolo di stringa con una lunghezza minima di 5 e massima di 100 caratteri. Quando chiamo questo endpoint tramite Postman e passo un testo con una dimensione di 3, genera un'eccezione come di seguito.

from typing import Optional
from fastapi import FastAPI, Query
import uvicorn

app = FastAPI()

@app.get("/orders/")
async def read_orders(query: Optional[str] = Query(None, min_length=5, max_length=100)): #defining the constraints
    results = {"order": [{"order_id": "Order_1"}, {"order_id": "Order_2"}]}
    return results
    if query:
        results.update({"query": query})

if __name__ == "__main__":
    uvicorn.run("parameter-validations:app")

      
                
Screenshot created by the author

Nell'esempio seguente, ho aggiunto un vincolo numerico con un valore minimo di 1 e un massimo di 100. Quando chiamo questo endpoint tramite Postman e passo 0, genera un'eccezione come di seguito.

from typing import Optional
from fastapi import FastAPI, Query
import uvicorn
app = FastAPI()

@app.get("/orders/")
async def read_items(order_count: int = Query(gt=1, lt=100)): # defining the constraints
    results = {"order_count": order_count}
    return results

if __name__ == "__main__":
    uvicorn.run("parameter-validations:app")

      
                
Screenshot created by the author

Pydantic è una libreria Python utilizzata per eseguire la serializzazione e la convalida dei dati.

FastAPI ha l'integrazione con Pydantic . Ciò garantisce in fase di esecuzione di analizzare, valutare e informare l'utente tramite l'IDE sugli errori relativi al tipo.

Di seguito puoi trovare un esempio di messaggio di errore;

fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that False is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/

La creazione di prodotti di dati richiede che molti team diversi lavorino insieme; ad esempio scienza dei dati, apprendimento automatico, ingegneria del software, ecc. In questa collaborazione interfunzionale l'allineamento sulla gestione degli errori e sulla messaggistica diventa cruciale. FastAPI supporta la gestione degli errori personalizzata con messaggi e codici di stato.

from fastapi import FastAPI, HTTPException
import uvicorn

app = FastAPI()

cities = {1: "Berlin", 2: "Hamburg", 3: "München"}


@app.get("/cities/{city_id}")
async def read_city_id(city_id: int):

    if city_id not in cities:
        raise HTTPException(status_code=404, detail="City id is not found") # status code and error message is defined

    results = {"city": cities[city_id]}
    return results


if __name__ == "__main__":
    uvicorn.run("error-message:app")

      
                
Screenshot created by the author

FastAPI supporta gli sviluppatori con endpoint interattivi e facili da testare generati automaticamente nel browser. Seguendo il link sottostante, verrai indirizzato ai percorsi che hai generato.

http://localhost:8000/docs

      
                
Screenshot created by the author

Screenshot creato dall'autore

La documentazione consente agli utenti di testare gli endpoint creati. Devi solo fare clic sul pulsante "Provalo" .

Screenshot creato dall'autore

Per testare le convalide numeriche, ho passato 0 al conteggio degli ordini e l'API ha restituito automaticamente il messaggio di errore e lo stato 422.

Servizio di modelli di machine learning con FastAPI

Poiché abbiamo appreso le basi di FastAPI, siamo pronti a usarlo per servire i nostri modelli di machine learning.

In questo esempio, ho utilizzato un set di dati di un'auto usata per prevedere il valore dell'auto. Il set di dati contiene le caratteristiche delle auto dal marchio a quanti chilometri sono stati percorsi con l'auto. Per semplificare l'esempio, non condividerò i passaggi di pulizia dei dati, preparazione dei dati e costruzione del modello, ma fornirò tutto in un file pickle.

Il codice Python carica il file pickle, crea un endpoint di previsione e restituisce il prezzo previsto dell'auto.

from fastapi import FastAPI
import joblib
import numpy as np
import pandas as pd
import uvicorn

# passing title, version and description parameters to the class object
app = FastAPI(
    title="Car Price Prediction",
    version="1.0",
    description="Model type: Linear Regression",
)

# loading previously saved pickle file
model = joblib.load("./LinearRegressionModel.pkl")

# creating predict end point
@app.get("/api/predict")
async def predict(
    name: str, company: str, year: int, kms_driven: float, fuel_type: str
):
    result = model.predict(
        pd.DataFrame(
            columns=["name", "company", "year", "kms_driven", "fuel_type"],
            data=np.array([name, company, year, kms_driven, fuel_type]).reshape(1, 5),
        )
    )[0]
    return result


if __name__ == "__main__":
    uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)

      
                
Screenshot created by the author
Screenshot created by the author

Conclusione

FastAPI è già diventato il framework di riferimento per scopi di servizio API nel dominio dei dati. Ogni giorno leggo ancora un altro articolo che i team di dati sono migrati a FastAPI e quanto traggono vantaggio da questo cambiamento. Non vedo l'ora di vedere altri aggiornamenti nei prossimi mesi e anni.

Complimenti a Sebastián Ramírez , al suo team e a tutti i contributori!

Grazie mille per aver letto

Per la mia serie di prodotti di dati , puoi controllare i link qui sotto;

Data Product Manager: il lavoro più cruciale del 21° secolo

Product Thinking per i team di dati

Vuoi vedere il nostro menu "Dati prodotto"?

Rivoluzione del prodotto dati

Mi trovi su Linkedin e Mentoring Club