FastAPI
FastAPI framework, alte prestazioni, facile da imparare, rapido da implementare, pronto per il rilascio in produzione
Documentazione: https://fastapi.tiangolo.com
Codice Sorgente: https://github.com/fastapi/fastapi
FastAPI è un web framework moderno e veloce (a prestazioni elevate) che serve a creare API con Python 3.6+ basato sulle annotazioni di tipo di Python.
Le sue caratteristiche principali sono:
- Velocità: Prestazioni molto elevate, alla pari di NodeJS e Go (grazie a Starlette e Pydantic). Uno dei framework Python più veloci in circolazione.
- Veloce da programmare: Velocizza il lavoro consentendo il rilascio di nuove funzionalità tra il 200% e il 300% più rapidamente. *
- Meno bug: Riduce di circa il 40% gli errori che commettono gli sviluppatori durante la scrittura del codice. *
- Intuitivo: Grande supporto per gli editor di testo con autocompletamento in ogni dove. In questo modo si può dedicare meno tempo al debugging.
- Facile: Progettato per essere facile da usare e imparare. Si riduce il tempo da dedicare alla lettura della documentazione.
- Sintentico: Minimizza la duplicazione di codice. Molteplici funzionalità, ognuna con la propria dichiarazione dei parametri. Meno errori.
- Robusto: Crea codice pronto per la produzione con documentazione automatica interattiva.
- Basato sugli standard: Basato su (e completamente compatibile con) gli open standard per le API: OpenAPI (precedentemente Swagger) e JSON Schema.
* Stima basata sull'esito di test eseguiti su codice sorgente di applicazioni rilasciate in produzione da un team interno di sviluppatori.
Sponsor¶
Recensioni¶
"[...] I'm using FastAPI a ton these days. [...] I'm actually planning to use it for all of my team's ML services at Microsoft. Some of them are getting integrated into the core Windows product and some Office products."
"We adopted the FastAPI library to spawn a REST server that can be queried to obtain predictions. [for Ludwig]"
"Netflix is pleased to announce the open-source release of our crisis management orchestration framework: Dispatch! [built with FastAPI]"
"I’m over the moon excited about FastAPI. It’s so fun!"
"Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted Hug to be - it's really inspiring to see someone build that."
"If you're looking to learn one modern framework for building REST APIs, check out FastAPI [...] It's fast, easy to use and easy to learn [...]"
"We've switched over to FastAPI for our APIs [...] I think you'll like it [...]"
Typer, la FastAPI delle CLI¶
Se stai sviluppando un'app CLI da usare nel terminale invece che una web API, ti consigliamo Typer.
Typer è il fratello minore di FastAPI. Ed è stato ideato per essere la FastAPI delle CLI. ⌨️ 🚀
Requisiti¶
Python 3.6+
FastAPI è basata su importanti librerie:
Installazione¶
$ pip install fastapi
---> 100%
Per il rilascio in produzione, sarà necessario un server ASGI come Uvicorn oppure Hypercorn.
$ pip install uvicorn[standard]
---> 100%
Esempio¶
Crea un file¶
- Crea un file
main.py
con:
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = Optional[None]):
return {"item_id": item_id, "q": q}
Oppure usa async def
...
Se il tuo codice usa async
/ await
, allora usa async def
:
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
Nota:
e vuoi approfondire, consulta la sezione "In a hurry?" su async
e await
nella documentazione.
Esegui il server¶
Puoi far partire il server così:
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
Informazioni sul comando uvicorn main:app --reload
...
Vediamo il comando uvicorn main:app
in dettaglio:
main
: il filemain.py
(il "modulo" Python).app
: l'oggetto creato dentromain.py
con la riga di codiceapp = FastAPI()
.--reload
: ricarica il server se vengono rilevati cambiamenti del codice. Usalo solo durante la fase di sviluppo.
Testa l'API¶
Apri il browser all'indirizzo http://127.0.0.1:8000/items/5?q=somequery.
Vedrai la seguente risposta JSON:
{"item_id": 5, "q": "somequery"}
Hai appena creato un'API che:
- Riceve richieste HTTP sui paths
/
and/items/{item_id}
. - Entrambi i paths accettano
GET
operations (conosciuti anche come HTTP methods). - Il path
/items/{item_id}
ha un path parameteritem_id
che deve essere unint
. - Il path
/items/{item_id}
ha unastr
query parameterq
.
Documentazione interattiva dell'API¶
Adesso vai all'indirizzo http://127.0.0.1:8000/docs.
Vedrai la documentazione interattiva dell'API (offerta da Swagger UI):
Documentazione interattiva alternativa¶
Adesso accedi all'url http://127.0.0.1:8000/redoc.
Vedrai la documentazione interattiva dell'API (offerta da ReDoc):
Esempio più avanzato¶
Adesso modifica il file main.py
per ricevere un body da una richiesta PUT
.
Dichiara il body usando le annotazioni di tipo standard di Python, grazie a Pydantic.
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = Optional[None]
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
Il server dovrebbe ricaricarsi in automatico (perché hai specificato --reload
al comando uvicorn
lanciato precedentemente).
Aggiornamento della documentazione interattiva¶
Adesso vai su http://127.0.0.1:8000/docs.
- La documentazione interattiva dell'API verrà automaticamente aggiornata, includendo il nuovo body:
- Fai click sul pulsante "Try it out", che ti permette di inserire i parametri per interagire direttamente con l'API:
- Successivamente, premi sul pulsante "Execute". L'interfaccia utente comunicherà con la tua API, invierà i parametri, riceverà i risultati della richiesta, e li mostrerà sullo schermo:
Aggiornamento della documentazione alternativa¶
Ora vai su http://127.0.0.1:8000/redoc.
- Anche la documentazione alternativa dell'API mostrerà il nuovo parametro della query e il body:
Riepilogo¶
Ricapitolando, è sufficiente dichiarare una sola volta i tipi dei parametri, del body, ecc. come parametri di funzioni.
Questo con le annotazioni per i tipi standard di Python.
Non c'è bisogno di imparare una nuova sintassi, metodi o classi specifici a una libreria, ecc.
È normalissimo Python 3.6+.
Per esempio, per un int
:
item_id: int
o per un modello Item
più complesso:
item: Item
...e con quella singola dichiarazione hai in cambio:
- Supporto per gli editor di testo, incluso:
- Autocompletamento.
- Controllo sulle annotazioni di tipo.
- Validazione dei dati:
- Errori chiari e automatici quando i dati sono invalidi.
- Validazione anche per gli oggetti JSON più complessi.
- Conversione dei dati di input: da risorse esterne a dati e tipi di Python. È possibile leggere da:
- JSON.
- Path parameters.
- Query parameters.
- Cookies.
- Headers.
- Form.
- File.
- Conversione dei dati di output: converte dati e tipi di Python a dati per la rete (come JSON):
- Converte i tipi di Python (
str
,int
,float
,bool
,list
, ecc). - Oggetti
datetime
. - Oggetti
UUID
. - Modelli del database.
- ...e molto di più.
- Converte i tipi di Python (
- Generazione di una documentazione dell'API interattiva, con scelta dell'interfaccia grafica:
- Swagger UI.
- ReDoc.
Tornando al precedente esempio, FastAPI:
- Validerà che esiste un
item_id
nel percorso delle richiesteGET
ePUT
. - Validerà che
item_id
sia di tipoint
per le richiesteGET
ePUT
.- Se non lo è, il client vedrà un errore chiaro e utile.
- Controllerà se ci sia un parametro opzionale chiamato
q
(per esempiohttp://127.0.0.1:8000/items/foo?q=somequery
) per le richiesteGET
.- Siccome il parametro
q
è dichiarato con= None
, è opzionale. - Senza il
None
sarebbe stato obbligatorio (come per il body della richiestaPUT
).
- Siccome il parametro
- Per le richieste
PUT
su/items/{item_id}
, leggerà il body come JSON, questo comprende:- verifica che la richiesta abbia un attributo obbligatorio
name
e che sia di tipostr
. - verifica che la richiesta abbia un attributo obbligatorio
price
e che sia di tipofloat
. - verifica che la richiesta abbia un attributo opzionale
is_offer
e che sia di tipobool
, se presente. - Tutto questo funzionerebbe anche con oggetti JSON più complessi.
- verifica che la richiesta abbia un attributo obbligatorio
- Convertirà da e a JSON automaticamente.
- Documenterà tutto con OpenAPI, che può essere usato per:
- Sistemi di documentazione interattivi.
- Sistemi di generazione di codice dal lato client, per molti linguaggi.
- Fornirà 2 interfacce di documentazione dell'API interattive.
Questa è solo la punta dell'iceberg, ma dovresti avere già un'idea di come il tutto funzioni.
Prova a cambiare questa riga di codice:
return {"item_name": item.name, "item_id": item_id}
...da:
... "item_name": item.name ...
...a:
... "item_price": item.price ...
...e osserva come il tuo editor di testo autocompleterà gli attributi e sarà in grado di riconoscere i loro tipi:
Per un esempio più completo che mostra più funzionalità del framework, consulta Tutorial - Guida Utente.
Spoiler alert: il tutorial - Guida Utente include:
- Dichiarazione di parameters da altri posti diversi come: headers, cookies, form fields e files.
- Come stabilire vincoli di validazione come
maximum_length
oregex
. - Un sistema di Dependency Injection facile da usare e molto potente. e potente.
- Sicurezza e autenticazione, incluso il supporto per OAuth2 con token JWT e autenticazione HTTP Basic.
- Tecniche più avanzate (ma ugualmente semplici) per dichiarare modelli JSON altamente nidificati (grazie a Pydantic).
- E altre funzionalità (grazie a Starlette) come:
- WebSockets
- GraphQL
- test molto facili basati su
requests
epytest
- CORS
- Cookie Sessions
- ...e altro ancora.
Prestazioni¶
Benchmark indipendenti di TechEmpower mostrano che FastAPI basato su Uvicorn è uno dei framework Python più veloci in circolazione, solamente dietro a Starlette e Uvicorn (usate internamente da FastAPI). (*)
Per approfondire, consulta la sezione Benchmarks.
Dipendenze opzionali¶
Usate da Pydantic:
email-validator
- per la validazione di email.
Usate da Starlette:
requests
- Richiesto se vuoi usare ilTestClient
.aiofiles
- Richiesto se vuoi usareFileResponse
oStaticFiles
.jinja2
- Richiesto se vuoi usare la configurazione template di default.python-multipart
- Richiesto se vuoi supportare il "parsing" conrequest.form()
.itsdangerous
- Richiesto per usareSessionMiddleware
.pyyaml
- Richiesto per il supporto delloSchemaGenerator
di Starlette (probabilmente non ti serve con FastAPI).graphene
- Richiesto per il supporto diGraphQLApp
.
Usate da FastAPI / Starlette:
uvicorn
- per il server che carica e serve la tua applicazione.orjson
- ichiesto se vuoi usareORJSONResponse
.ujson
- Richiesto se vuoi usareUJSONResponse
.
Puoi installarle tutte con pip install fastapi[all]
.
Licenza¶
Questo progetto è concesso in licenza in base ai termini della licenza MIT.