Costruire interfacce web moderne in Python spesso significa destreggiarsi tra più livelli, motori di templating, tool JavaScript e framework front-end, solo per far funzionare una UI di base. FastHTML offre un approccio più mirato: un framework minimale, Python-first, che semplifica lo sviluppo permettendoti di definire le interfacce direttamente nel codice, senza uscire dal linguaggio o gestire complessità extra.
Questo articolo esplora come funziona FastHTML, i suoi principi di progettazione fondamentali e come costruire applicazioni reali con esso—da pagine semplici a interfacce interattive e guidate dai dati.
Se vuoi consolidare le basi dello sviluppo backend prima di iniziare, ti consiglio di dare un'occhiata a questo tutorial sullo sviluppo backend in Python su DataCamp per una panoramica dei concetti e degli strumenti web principali.
Che cos'è FastHTML?
FastHTML è un framework Python snello progettato per semplificare lo sviluppo di interfacce web. Affronta sfide comuni in ambito di sviluppo, testing e prestazioni eliminando la necessità di una conoscenza approfondita di JavaScript o di gestire più file template.
Molti sviluppatori Python vogliono creare interfacce web senza doversi addentrare nelle complessità di uno stack JavaScript completo. FastHTML risponde a questa esigenza, consentendo di definire route e componenti HTML con poche, concise righe di codice Python.
Oltre alle interfacce di base, è facile estendere le applicazioni costruite con FastHTML incorporando funzionalità come autenticazione, caching, integrazione con database e styling personalizzato, migliorando notevolmente funzionalità ed esperienza utente.
Funzionalità e vantaggi di FastHTML
FastHTML ha molte funzionalità e vantaggi. Supera numerose sfide legate a sviluppo, testing e prestazioni.
FastHMTL ha molte funzionalità e vantaggi.
Sviluppo solo in Python: non ti serve funzionalità JavaScript aggiuntiva, solo Python. Il risultato sono progetti leggeri con meno file e meno boilerplate.
Dipendenze minime: FastHTML si basa su poche librerie esterne, quindi gli aggiornamenti sono semplici e la manutenzione è meno complessa.
Sicurezza. Meno dipendenze significa una superficie d'attacco più piccola.
Stack client/server unificato: usare un solo linguaggio e framework per logica e UI riduce il context switching, accelerando lo sviluppo.
Elementi HTML come oggetti Python nativi: FastHTML ti permette di usare elementi HTML come oggetti Python tramite attributi HTMX, senza JavaScript personalizzato.
Gestione asincrona delle richieste: FastHTML supporta l'elaborazione asincrona delle richieste, con bassa latenza e alta concorrenza.
Deployment flessibile: Le applicazioni finite possono essere distribuite su qualsiasi piattaforma che supporti Python.
FastHTML riduce la complessità tipicamente associata allo sviluppo di UI web, come la gestione di file template separati, script di supporto e pipeline di asset. Anche il testing è notevolmente semplificato, poiché lo stack Python unificato permette di snellire le fasi di validazione backend, frontend ed end-to-end.
Principi architetturali di base
FastHTML si basa su principi architetturali fondamentali: il layer di astrazione HTML pythonico, l'integrazione con lo standard ASGI e l'interattività guidata da HTMX.
Layer di astrazione HTML pythonico
FastHTML rappresenta ogni elemento HTML standard come una corrispondente funzione Python. Per esempio, il tag HTML <div> è rispecchiato dalla funzione Python Div(...), <a> diventa A(..., href=...) e così via.
Gli argomenti posizionali passati alle funzioni degli elementi Python vengono renderizzati come elementi figli nella struttura HTML risultante. Per esempio,
Div(
P("Hello, world!"),
Ul(Li("one"), Li("two")))Offerto da
produrrà questo output HTML:
<div><p>Hello, world!</p><ul><li>one</li><li>two</li></ul></div>Offerto da
Gli argomenti keyword diventano attributi HTML. Ad esempio, il codice Python
A("Docs", href="/docs", cls="button", hx_get="/info")Offerto da
viene renderizzato in
<ahref="/docs"class="button"hx-get="/info">Docs</a>Offerto da
Nota che la keyword cls mappa sull'attributo class in HTML. I trattini bassi nei nomi degli attributi (hx_get) vengono convertiti in trattini (hx-get).
FastHTML differisce la serializzazione, il che consente alle route di restituire oggetti Python invece di stringhe HTML grezze. Il framework converte l'albero di oggetti Python in HTML solo all'ultimo passaggio, appena prima di inviare la risposta. Questo design mantiene la logica pulita e libera da manipolazioni manuali di stringhe.
FastHTML offre i vantaggi di un templating type-safe e della gestione degli attributi, producendo codice più chiaro e manutenibile. Le API degli elementi e gli attributi compaiono nelle definizioni di funzioni o classi, rendendo il codice autoesplicativo. Nomi sicuri per Python (da hx-post a hx_post) evitano la necessità di manipolare manualmente stringhe.
Il refactoring è più sicuro e affidabile. Rinominare un parametro aggiorna automaticamente gli utilizzi. Inoltre, i test unitari possono istanziare e validare direttamente gli oggetti componente, evitando di dover ricorrere a regex sull'HTML renderizzato.
Integrazione con ASGI (Asynchronous Server Gateway Interface)
FastHTML si integra con ASGI, uno standard guidato dalla community per Python che abilita una comunicazione non bloccante ed event-driven tra web server e applicazioni. ASGI alimenta i framework web Python moderni supportando operazioni asincrone al cuore dello stack web.
Web server come Uvicorn aderiscono alle specifiche ASGI, garantendo compatibilità e scalabilità. Framework come Starlette e FastHTML si basano su ASGI per offrire routing robusto, middleware e API di alto livello.
Questa architettura offre alta concorrenza, supporto integrato per HTTP, WebSocket ed eventi inviati dal server, e una gestione efficiente e event-driven delle richieste. Usando un event loop asyncio, le app ASGI evitano l'overhead di un thread OS per connessione, consentendo a pochi thread di gestire migliaia di client. L'oggetto scope standardizzato e il design non bloccante permettono ai handler di mettersi in attesa per I/O senza rallentare le altre richieste.
Interattività guidata da HTMX
Con la libreria HTMX, puoi estendere gli attributi HTML standard con attributi hx-*. Questi elementi consentono di inviare richieste HTTP e sostituire dinamicamente il contenuto della pagina con frammenti restituiti dal server. Non serve JavaScript personalizzato.
Iniziare con FastHTML
Iniziare con FastHTML è semplice. Di seguito abbiamo descritto i passaggi principali.
Installazione e setup
Per installare FastHTML, usa pip install python-fasthtml.
Prima app
Costruiamo una semplice app per mostrare un'intestazione e un messaggio.
from fasthtml.common import FastHTML, serve, Div, H1, P
app = FastHTML()@app.get("/")defhome():return Div(
H1("Welcome to FastHTML"),
P("Hello, world!"))if __name__ =="__main__":
serve()Offerto da
Esegui il file digitando python app.py nel terminale.
Fai Ctrl+clic sul link per aprire la tua app. Vedrai una pagina:
Definire una route
Aggiungiamo una pagina About alla nostra app. Usa il seguente codice:
from fasthtml.common import FastHTML, serve, Div, H1, P, A
app = FastHTML()@app.get("/")defhome():return Div(
H1("Welcome to FastHTML"),
P("Hello, world!"),
A("About", href="/about"))@app.get("/about")defabout():return Div(
H1("About"),
P("This is the about page."),
A("Home", href="/"))if __name__ =="__main__":
serve()Offerto da
La riga A("About", href="/about") crea un link dalla home page alla pagina about. Il decorator @app.get("/about") definisce la route per la pagina about.
Implementazione di base
In FastHTML, i pattern UI riutilizzabili sono incapsulati in semplici funzioni Python. Queste funzioni restituiscono oggetti componente annidati, consentendoti di trattare widget come una Card o una Navbar come oggetti richiamabili.
Definire markup, attributi e styling in un unico posto garantisce coerenza in tutta l'applicazione. Quando importi e usi queste funzioni, qualsiasi modifica visiva o comportamentale si propaga automaticamente.
Questo approccio riduce il codice ripetuto, rendendo il tuo frontend facile da testare e rifattorizzare come qualsiasi modulo Python.
Per dimostrarlo, creiamo una pagina che mostra due semplici card.
from fasthtml.common import*defCard(title:str, body:str):
children =[
H2(title, cls="card-title"),
P(body, cls="card-body")]return Div(*children,
cls="card",
style="background- border-radius: 0.5rem;")
app = FastHTML()@app.get("/")defhome():return Div(
Card("Welcome","A welcome card."),
P(''),
Card("A Second Card","This is another card."),
cls="page")Offerto da
La funzione Card accetta due stringhe, title e body, come argomenti e restituisce un elemento card con uno styling di base. Nella route home, questo widget viene usato due volte senza duplicare il codice. Definiamo la Card una sola volta e la riutilizziamo quando serve, assicurando markup e styling coerenti in tutta l'app.
Creare widget UI in questo modo offre diversi vantaggi.
Riduzione della duplicazione: imposti markup e styling una volta sola e riutilizzi il componente ovunque serva. Aggiornamenti o fix si propagano automaticamente.
Design UI coerente: ogni istanza del componente mantiene la stessa struttura, le stesse classi e lo stesso comportamento. Questo rafforza un look and feel uniforme in tutta l'applicazione.
Manutenzione semplificata: una codebase più piccola e DRY significa meno file da gestire, meno boilerplate e uno sviluppo più efficiente.
Uso avanzato
Questa sezione esplora tecniche avanzate in FastHTML, tra cui gestione dei form, validazione e pattern di feedback sugli errori. Sfruttando classi Python e componenti strutturati, puoi costruire form robusti e user-friendly mantenendo codice pulito e testabile.
Gestione dei form e validazione
FastHTML semplifica la gestione dei form generando automaticamente HTML a partire da classi Python e fornendo un data binding lineare per elaborare gli invii dei form.
Per esempio, considera il seguente codice.
from fasthtml.common import*from dataclasses import dataclass
@dataclassclassProfile:
name:str;
email:str;
age:int
profile_form = Form(method="post", action="/profile")(
Fieldset(
Label("Name", Input(name="name")),
Label("Email", Input(name="email")),
Label("Age", Input(name="age")),),
Button("Submit",type="submit"),)# Instantiate app
app = FastHTML()# GET / serves the form (FastHTML will serialize the component to HTML)@app.get("/")defhome():return profile_form
# Simple POST handler to echo back submitted data@app.post("/profile")defprofile(data: Profile):return Div(
H1("Profile Submitted"),
P(f"Name: {data.name}"),
P(f"Email: {data.email}"),
P(f"Age: {data.age}"))Offerto da
Questo codice genera il seguente HTML per il form. FastHTML analizza automaticamente i dati del form nell'oggetto Profile, supponendo nomi di campo compatibili. Sotto il cofano, ciò può basarsi su parsing in stile Starlette e su un layer di validazione personalizzato.
Una volta inviato il form, FastHTML analizza i dati del form nell'oggetto Profile. La route profile quindi restituisce una pagina di conferma, mostrando i valori inviati direttamente dall'oggetto data. Questo approccio semplifica la gestione dei form, riduce il boilerplate e garantisce un forte typing dei dati in tutta l'applicazione.
È sempre una buona idea validare gli input del form. Aggiungi logica di validazione riscrivendo la route /profile come segue.
@app.post("/profile")defsubmit_profile(data: Profile):# Form validationifnot data.name.strip():raise HTTPException(status_code=400, detail="Name is required")ifnot data.email.strip()or"@"notin data.email:raise HTTPException(status_code=400, detail="A valid email is required")if data.age <0:raise HTTPException(status_code=400, detail="Age must be non-negative")# If validation passes, render the resultreturn Div(
H1("Profile Submitted"),
P(f"Name: {data.name}"),
P(f"Email: {data.email}"),
P(f"Age: {data.age}"))Offerto da
Se name manca, email manca o age è negativo, l'utente riceve un messaggio di errore chiaro. Sollevando un'HTTPException con status code 400, l'applicazione comunica lo specifico errore di validazione, aiutando l'utente a correggere l'input prima di inviare di nuovo il form.
Un modo più robusto di gestire dati mancanti o non validi è effettuare controlli di errore espliciti e fornire feedback user-friendly. Ad esempio, riscrivi il codice come segue.
from fasthtml.common import*from dataclasses import dataclass
@dataclassclassProfile:
name:str
email:str
age:intdefprofile_form(data=None, errors=None):
data = data or{}
errors = errors or{}return Form(
Fieldset(
Label("Name",
Input(
name="name",
value=data.get("name",""),
placeholder="Your name")),
Small(errors.get("name",""), cls="error-text"),
Label("Email",
Input(
name="email",type="email",
value=data.get("email",""),
placeholder="[email protected]")),
Small(errors.get("email",""), cls="error-text"),
Label("Age",
Input(
name="age",type="number",
value=str(data.get("age","")),
placeholder="Age")),
Small(errors.get("age",""), cls="error-text"),),
Button("Submit",type="submit"), method="post", action="/profile",id="profile-form", hx_swap="outerHTML")
app = FastHTML()@app.get("/")defhome():return Div(
H1("Create Your Profile"),
profile_form())@app.post("/profile")asyncdefsubmit_profile(request):
form =await request.form()
data ={"name": form.get("name","").strip(),"email": form.get("email","").strip(),}
errors ={}# Validate nameifnot data["name"]:
errors["name"]="Name is required. "# Validate emailifnot data["email"]:
errors["email"]="Email is required. "elif"@"notin data["email"]:
errors["email"]="Enter a valid email address."# Validate age
age_raw = form.get("age","").strip()try:
age =int(age_raw)if age <0:raise ValueError()
data["age"]= age
except ValueError:
errors["age"]="Age must be a non-negative integer. "if errors:# re-render form with submitted values and error messagesreturn Div(
H1("Create Your Profile"),
profile_form(data, errors))# Success path
profile = Profile(**data)return Div(
H1("Profile Submitted"),
P(f"Name: {profile.name}"),
P(f"Email: {profile.email}"),
P(f"Age: {profile.age}"))if __name__ =="__main__":
serve()Offerto da
Se l'utente salta un campo obbligatorio o fornisce un input non valido, vedrà il form renderizzato di nuovo con i valori inviati e gli opportuni messaggi di errore accanto a ciascun campo. Questo approccio migliora l'esperienza utente indicando chiaramente cosa va corretto.
Una volta compilati tutti i campi e inviato, otterrai una schermata simile alla seguente.
Autenticazione e gestione della sessione
Implementare i flussi di autenticazione
In FastHTML, i dati di sessione sono gestiti tramite l'oggetto request.session, che si comporta come un dizionario Python. Puoi memorizzare dati nella sessione impostando coppie chiave-valore, ad esempio session['user_id'] = 123. Per recuperare i dati di sessione, usa read (user_id = session.get('user_id')). Per cancellare tutti i dati di sessione, chiama session.clear().
Dietro le quinte, FastHTML serializza il dizionario di sessione in un cookie firmato, che persiste tra le richieste. Questo approccio ti permette di gestire autenticazione utente e stato di sessione usando pattern Python familiari.
Schema per costruire workflow di autenticazione
Per costruire un workflow di autenticazione, segui questi passaggi.
Configura le sessioni: aggiungi SessionMiddleware con una secret_key robusta. Una volta configurato, request.session è disponibile in ogni handler.
Modello utente e gestione password: definisci uno schema utente (usando dataclass, modello Pydantic o ORM) che includa uno username e password_hash. Usa una funzione di hashing (ad es. hashlib, pbkdf2_hmac, bcrypt) per memorizzare e verificare le password.
Flusso di registrazione*: crea una route GET /register per mostrare un form di signup. * Usa POST /register per validare l'input del form, fare l'hash della password, salvare il record utente, impostare session['user_id'] e reindirizzare a una pagina protetta o alla dashboard.
Flusso di login*: crea una route GET /login per mostrare il form di login.* Usa POST /login per verificare le credenziali. In caso di successo, scrivi session['user_id'] e reindirizza; in caso di fallimento, renderizza di nuovo il form con un messaggio di errore.
Protezione delle route: crea una funzione helper o un decorator che controlli session.get('user_id'). Se l'utente non è autenticato, reindirizza a /login; altrimenti consenti l'accesso alla route richiesta.
Flusso di logout: nella route GET /logout, chiama session.clear()` per rimuovere i dati di sessione e reindirizzare l'utente alla pagina di login o alla home.
Integrazione con database
Un Object-Relational Mapper (ORM) mappa le classi alle tabelle del database, permettendoti di interrogare i dati usando oggetti nativi invece di SQL grezzo. Opzioni popolari includono SQLAlchemy e l'ORM di Django.
FastHTML ha un'interfaccia "simile a un ORM" che si integra con qualsiasi ORM o libreria di query Python compatibile con async. Di default usa SQLite ma può integrarsi con qualsiasi backend di database. Per esempio, considera il seguente codice.
# Database setup (SQLite by default, but backend can change)from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import Column, Integer, String, select
from fasthtml.common import*
DATABASE_URL ="sqlite+aiosqlite:///./test.db"# Change backend here (e.g., PostgreSQL)
engine = create_async_engine(DATABASE_URL, echo=True)
SessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()# ORM modelclassUser(Base):
__tablename__ ="users"id= Column(Integer, primary_key=True)
name = Column(String)# FastHTML app
app = FastHTML()@app.get("/")asyncdeflist_users():asyncwith SessionLocal()as session:
result =await session.execute(select(User))
users = result.scalars().all()return Div(
H1("Users"),
Ul(*[Li(user.name)for user in users]))if __name__ =="__main__":import asyncio
asyncdefinit_db():asyncwith engine.begin()as conn:await conn.run_sync(Base.metadata.create_all)
asyncio.run(init_db())
serve()Offerto da
In un'applicazione FastHTML, interroghi i dati nello strato di database che preferisci, quindi passi i risultati ai componenti FastHTML per il rendering. Ad esempio, dopo aver recuperato i record dal database, puoi iterarli in un route handler e costruire strutture HTML come tabelle, liste o card personalizzate.
Le best practice restano valide: seleziona solo i campi necessari, filtra e ordina a livello di database e pagina risultati di grandi dimensioni. FastHTML ti aiuta a concentrarti sulla costruzione di front-end puliti e dinamici lasciando la gestione dei dati agli strumenti migliori per il tuo progetto.
Strategie di ottimizzazione delle prestazioni
Ci sono diversi modi per ottenere i migliori risultati con FastHTML. Di seguito abbiamo raccolto alcuni consigli.
Meccanismi di caching
Il caching migliora le prestazioni evitando lavoro ridondante a diversi livelli dell'applicazione. A livello di browser e CDN, usa gli header di cache control per trattenere asset statici come immagini, script e fogli di stile.
Nel tuo framework web, puoi mettere in cache intere risposte di route o parti costose. All'interno della tua app FastHTML, metti in cache risposte di route intere o componenti costosi, garantendo che le richieste ripetute tornino rapidamente senza ri-interrogare il database o rigenerare template.
In Python, puoi implementare il caching a livello di funzione utilizzando decorator. Ad esempio, il decorator incorporato functools.lru_cache può memorizzare i risultati di una funzione helper che recupera i dati utente. Per esempio, potresti usare questo decorator per mettere in cache le chiamate al database:
from functools import lru_cache
@lru_cache(maxsize=64)deffetch_user_profile(user_id):# simulate an expensive database callreturn db.get_user(user_id)@app.get("/profile/{user_id}")defprofile(user_id:int):
profile = fetch_user_profile(user_id)return Div(P(profile.name), P(profile.email))Offerto da
Code di task asincrone
Le applicazioni web restano reattive delegando i task che richiedono tempo fuori dal ciclo della richiesta. Invece di bloccare il server mentre generi report, invii email o elabori dati, questi task vengono accodati ed eseguiti in background.
Con questo approccio, la tua applicazione invia una risposta immediata all'utente mentre worker, in processi o thread separati, elaborano i task in coda in modo asincrono.
FastHTML supporta l'esecuzione di task in background integrandosi con il BackgroundTasks di Starlette. Ecco un esempio che mostra come inviare un'email di benvenuto dopo la registrazione dell'utente.
from fasthtml.common import FastHTML, serve, Div, Form, Input, Button
from starlette.background import BackgroundTasks
app = FastHTML()defsend_welcome_email(email:str):# expensive or time consuming work...@app.post("/signup")defsignup(background_tasks: BackgroundTasks, request):
form =await request.form()
email = form["email"]# schedule the email task
background_tasks.add_task(send_welcome_email, email)return Div("Thanks for signing up! You will receive an email shortly.")Offerto da
Applicazioni reali
FastHTML è un framework versatile che può alimentare un'ampia gamma di applicazioni web. Vediamo come potresti affrontare la costruzione di una piattaforma e-commerce e di una dashboard dati usando FastHTML.
Blueprint per una piattaforma e-commerce
Costruiamo una piattaforma ecommerce con FastHTML. Inizia modellando i tuoi dati principali come classi ORM o dataclass Python: prodotti, utenti e articoli del carrello.
Crea una pagina di elenco prodotti che iteri sui record. Per ogni prodotto, usa un componente Python riutilizzabile, come una Card, per mostrare prodotto, immagine, nome, prezzo e un pulsante "Aggiungi al carrello". Questo pulsante include attributi HTMX come hx_post e hx_target, che gli permettono di inviare una richiesta per aggiungere l'articolo al carrello in sessione dell'utente senza ricaricare l'intera pagina.
Il carrello è memorizzato nel dizionario di session dell'utente sul server. Nell'intestazione del sito, includi un componente riepilogo del carrello che si aggiorna dinamicamente con HTMX ogni volta che gli articoli vengono aggiunti o rimossi.
La pagina del carrello legge i dati di sessione per renderizzare ciascun articolo insieme al totale complessivo. Offre anche un form di checkout collegato a una classe Python per la validazione. Quando l'utente invia il form, l'app crea un record d'ordine e svuota il carrello in sessione.
Implementazione di una dashboard dati
Una dashboard dati in FastHTML combina componenti Python con le tue sorgenti dati, usando HTMX per interattività e aggiornamenti in tempo reale. La tua logica backend (ad es. funzioni helper async, utility CRUD con cache o query ORM) recupera i dati necessari.
Da lì, progetti una pagina con widget riutilizzabili. Questi possono includere controlli di filtro (come menu a discesa, selettori di date o caselle di ricerca) per affinare le query, card KPI per mostrare metriche chiave, tabelle dati per elencare record o grafici incorporati per visualizzare trend e confronti.
Ogni widget è scritto come codice Python nativo, tipicamente un Div, Table o un componente Card personalizzato. FastHTML trasforma automaticamente questi oggetti in HTML al momento della risposta.
HTMX rende le dashboard interattive. Ad esempio, i widget di filtro possono usare hx_get e hx_post per richiedere dati filtrati al server, aggiornando dinamicamente tabelle o grafici senza richiedere un reload completo della pagina.
Analisi comparativa con i framework tradizionali
FastHTML si distingue da framework tradizionali come Django e Flask semplificando sia lo sviluppo sia le prestazioni. Vediamo come si confronta su fattori chiave come tempi di setup, efficienza del codice e benchmark prestazionali.
Velocità di sviluppo
FastHTML ha due vantaggi chiave rispetto a framework come Django e Flask: tempi di setup ed efficienza del codice.
Tempo di setup
L'approccio "batteries-included" di Django richiede diversi passaggi prima di poter servire la prima pagina: installare il pacchetto, eseguire django-admin startproject, configurare le impostazioni e definire un'app. Questo spesso comporta più file e molto boilerplate prima di scrivere logica reale.
Flask è più snello. Dopo il pip install, puoi scrivere un paio di route in un singolo file. Tuttavia, devi comunque configurare i template Jinja, le cartelle static e aggiungere JavaScript per l'interattività.
Con FastHTML, il setup è minimo.
Esegui pip install python-fasthtml uvicorn.
Definisci route e componenti HTML pythonici. Puoi farlo in un solo file.
Chiama serve().
Non serve un motore di template separato né la configurazione di una cartella static. Puoi iniziare a costruire subito.
Efficienza del codice
Con Django, anche una semplice pagina "Hello, world" richiede più file: views.py, urls.py, settings.py, templates/hello.html, oltre all'impalcatura di ORM e admin.
Flask semplifica il processo a un singolo file, ma devi comunque scrivere manualmente HTML nei template Jinja o in stringhe inline, e JavaScript per l'interattività.
FastHTML ti permette di definire la UI come oggetti Python, quindi non serve cambiare file o linguaggi. HTMX gestisce l'interattività in modo dichiarativo senza script personalizzati. Il risultato sono meno righe di codice, nessun template o pipeline di asset statici separati e un'unica superficie testabile per markup e comportamento.
Benchmark delle prestazioni
Studi di benchmark mostrano che i framework asincroni superano quelli sincroni sotto alta concorrenza. Ad esempio, in un confronto prestazionale tra Flask, Django, Quart e FastAPI, i framework asincroni (Quart e FastAPI) hanno gestito molte più richieste al secondo rispetto alle controparti sincrone.
Ciò è attribuito ai loro meccanismi di gestione non bloccante delle richieste, che consentono di gestire più richieste simultaneamente senza attendere il completamento delle operazioni di I/O.
Tabella di confronto
Per capire meglio come FastHTML si confronta con framework più affermati, la tabella seguente evidenzia le differenze chiave in termini di tempi di setup, efficienza del codice e caratteristiche prestazionali tra FastHTML, Flask e Django.
Feature
FastHTML
Flask
Django
Setup Time
Minimo: pip install, definisci route e componenti in un file, chiama serve()
Moderato: avvio rapido con un singolo file, ma richiede template Jinja e setup della cartella static
Lungo: richiede scaffolding del progetto, configurazione delle impostazioni, definizione delle app e più file
Template Engine
Non necessario—usa oggetti Python per l'HTML
Richiesto il motore di templating Jinja2 per le view
Usa i Template di Django con un linguaggio e una directory separati
Front-End Interactivity
Dichiarativa tramite HTMX, non serve JavaScript
JavaScript manuale tipicamente necessario per l'interattività
Richiede JavaScript per l'interattività, spesso con tool esterni
Code Efficiency
Alta: poco boilerplate, HTML pythonico, logica + UI unificate
Moderata: routing conciso ma l'HTML vive nei template, l'interattività necessita JS personalizzato
Bassa: logica, template e configurazione sono distribuiti in molti file
Performance (Concurrency)
Alta: basato su ASGI con supporto async, adatto ad alta concorrenza
Inferiore: basato su WSGI, gestione sincrona salvo estensioni async
Inferiore: basato su WSGI e sincrono di default; richiede setup aggiuntivo per il supporto async
Linee di codice per "Hello, World"
Pochissime righe in un file
Poche righe, ma richiede template o HTML inline
Più file tra view, URL, template e impostazioni
Conclusione
FastHTML offre un approccio nuovo e pythonico alla costruzione di applicazioni web, combinando la flessibilità degli oggetti Python con la potenza dell'esecuzione asincrona. Eliminando la necessità di file template separati, pipeline di asset statici e framework frontend, FastHTML snellisce lo sviluppo e ti permette di creare interfacce dinamiche e interattive in modo rapido ed efficiente.
Con HTMX per l'interattività, ASGI per le prestazioni e un'integrazione fluida con ORM compatibili con async, FastHTML è adatto a progetti web moderni—da piattaforme e-commerce a dashboard dati e oltre. Il setup minimo, il boilerplate ridotto e la codebase unificata lo rendono una scelta interessante per chi cerca un'alternativa leggera e produttiva ai framework tradizionali come Django e Flask.
Per chi è interessato a esplorare strumenti e approcci correlati allo sviluppo web in Python, le seguenti risorse offrono i prossimi passi consigliati.
FastHTML elimina la necessità di file template separati, configurazioni di asset statici e framework frontend. Si concentra su uno sviluppo solo in Python con HTMX per l'interattività.
Posso usare FastHTML per applicazioni su larga scala?⌄
Sì. L'architettura di FastHTML (Python + HTMX + ASGI) scala bene per applicazioni moderne e ad alte prestazioni. Per progetti grandi, puoi modularizzare la codebase con componenti riutilizzabili.
FastHTML supporta interattività dinamica come AJAX?⌄
Sì. FastHTML usa HTMX per gestire l'interattività in modo dichiarativo, abilitando aggiornamenti parziali della pagina (simili ad AJAX) senza JavaScript personalizzato.
Posso distribuire applicazioni FastHTML nel cloud?⌄
Assolutamente. Le app FastHTML possono essere distribuite su qualsiasi piattaforma che supporti ASGI e Python, inclusi servizi come Vercel, Fly.io e DigitalOcean.
Mark Pedigo, PhD, è un affermato data scientist con competenze in data science per la sanità, programmazione e didattica. Con un dottorato in Matematica, una laurea in Informatica e un Professional Certificate in AI, Mark unisce conoscenze tecniche e problem solving pratico. La sua carriera comprende ruoli nella rilevazione delle frodi, nella previsione della mortalità infantile e nella previsione finanziaria, oltre a contributi al software di stima dei costi della NASA. Come docente, ha insegnato su DataCamp e alla Washington University di St. Louis e ha fatto da mentore a programmatori junior. Nel tempo libero, Mark si gode la natura del Minnesota con la moglie Mandy e il cane Harley e suona il pianoforte jazz.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Impara Python per lo sviluppo software, dalla scrittura di funzioni alla definizione di classi. Acquisisci le competenze necessarie per dare il via alla tua carriera da sviluppatore!
Crea API robuste e pronte per la produzione con FastAPI, padroneggiando operazioni HTTP, validazione ed esecuzione async per pipeline dati e ML efficienti.
Costruire interfacce web moderne in Python spesso significa destreggiarsi tra più livelli, motori di templating, tool JavaScript e framework front-end, solo per far funzionare una UI di base. FastHTML offre un approccio più mirato: un framework minimale, Python-first, che semplifica lo sviluppo permettendoti di definire le interfacce direttamente nel codice, senza uscire dal linguaggio o gestire complessità extra.
Questo articolo esplora come funziona FastHTML, i suoi principi di progettazione fondamentali e come costruire applicazioni reali con esso—da pagine semplici a interfacce interattive e guidate dai dati.
Se vuoi consolidare le basi dello sviluppo backend prima di iniziare, ti consiglio di dare un'occhiata a questo tutorial sullo sviluppo backend in Python su DataCamp per una panoramica dei concetti e degli strumenti web principali.
Che cos'è FastHTML?
FastHTML è un framework Python snello progettato per semplificare lo sviluppo di interfacce web. Affronta sfide comuni in ambito di sviluppo, testing e prestazioni eliminando la necessità di una conoscenza approfondita di JavaScript o di gestire più file template.
Molti sviluppatori Python vogliono creare interfacce web senza doversi addentrare nelle complessità di uno stack JavaScript completo. FastHTML risponde a questa esigenza, consentendo di definire route e componenti HTML con poche, concise righe di codice Python.
Oltre alle interfacce di base, è facile estendere le applicazioni costruite con FastHTML incorporando funzionalità come autenticazione, caching, integrazione con database e styling personalizzato, migliorando notevolmente funzionalità ed esperienza utente.
Funzionalità e vantaggi di FastHTML
FastHTML ha molte funzionalità e vantaggi. Supera numerose sfide legate a sviluppo, testing e prestazioni.
FastHMTL ha molte funzionalità e vantaggi.
FastHTML riduce la complessità tipicamente associata allo sviluppo di UI web, come la gestione di file template separati, script di supporto e pipeline di asset. Anche il testing è notevolmente semplificato, poiché lo stack Python unificato permette di snellire le fasi di validazione backend, frontend ed end-to-end.
Principi architetturali di base
FastHTML si basa su principi architetturali fondamentali: il layer di astrazione HTML pythonico, l'integrazione con lo standard ASGI e l'interattività guidata da HTMX.
Layer di astrazione HTML pythonico
FastHTML rappresenta ogni elemento HTML standard come una corrispondente funzione Python. Per esempio, il tag HTML
<div>è rispecchiato dalla funzione PythonDiv(...),<a>diventaA(..., href=...)e così via.Gli argomenti posizionali passati alle funzioni degli elementi Python vengono renderizzati come elementi figli nella struttura HTML risultante. Per esempio,
produrrà questo output HTML:
Gli argomenti keyword diventano attributi HTML. Ad esempio, il codice Python
viene renderizzato in
Nota che la keyword
clsmappa sull'attributoclassin HTML. I trattini bassi nei nomi degli attributi (hx_get) vengono convertiti in trattini (hx-get).FastHTML differisce la serializzazione, il che consente alle route di restituire oggetti Python invece di stringhe HTML grezze. Il framework converte l'albero di oggetti Python in HTML solo all'ultimo passaggio, appena prima di inviare la risposta. Questo design mantiene la logica pulita e libera da manipolazioni manuali di stringhe.
FastHTML offre i vantaggi di un templating type-safe e della gestione degli attributi, producendo codice più chiaro e manutenibile. Le API degli elementi e gli attributi compaiono nelle definizioni di funzioni o classi, rendendo il codice autoesplicativo. Nomi sicuri per Python (da
hx-postahx_post) evitano la necessità di manipolare manualmente stringhe.Il refactoring è più sicuro e affidabile. Rinominare un parametro aggiorna automaticamente gli utilizzi. Inoltre, i test unitari possono istanziare e validare direttamente gli oggetti componente, evitando di dover ricorrere a regex sull'HTML renderizzato.
Integrazione con ASGI (Asynchronous Server Gateway Interface)
FastHTML si integra con ASGI, uno standard guidato dalla community per Python che abilita una comunicazione non bloccante ed event-driven tra web server e applicazioni. ASGI alimenta i framework web Python moderni supportando operazioni asincrone al cuore dello stack web.
Web server come Uvicorn aderiscono alle specifiche ASGI, garantendo compatibilità e scalabilità. Framework come Starlette e FastHTML si basano su ASGI per offrire routing robusto, middleware e API di alto livello.
Questa architettura offre alta concorrenza, supporto integrato per HTTP, WebSocket ed eventi inviati dal server, e una gestione efficiente e event-driven delle richieste. Usando un event loop asyncio, le app ASGI evitano l'overhead di un thread OS per connessione, consentendo a pochi thread di gestire migliaia di client. L'oggetto scope standardizzato e il design non bloccante permettono ai handler di mettersi in attesa per I/O senza rallentare le altre richieste.
Interattività guidata da HTMX
Con la libreria HTMX, puoi estendere gli attributi HTML standard con attributi hx-*. Questi elementi consentono di inviare richieste HTTP e sostituire dinamicamente il contenuto della pagina con frammenti restituiti dal server. Non serve JavaScript personalizzato.
Iniziare con FastHTML
Iniziare con FastHTML è semplice. Di seguito abbiamo descritto i passaggi principali.
Installazione e setup
Per installare FastHTML, usa
pip install python-fasthtml.Prima app
Costruiamo una semplice app per mostrare un'intestazione e un messaggio.
Esegui il file digitando
pythonapp.pynel terminale.Fai Ctrl+clic sul link per aprire la tua app. Vedrai una pagina:
Definire una route
Aggiungiamo una pagina About alla nostra app. Usa il seguente codice:
La riga
A("About", href="/about")crea un link dalla home page alla pagina about. Il decorator@app.get("/about")definisce la route per la pagina about.Implementazione di base
In FastHTML, i pattern UI riutilizzabili sono incapsulati in semplici funzioni Python. Queste funzioni restituiscono oggetti componente annidati, consentendoti di trattare widget come una
Cardo unaNavbarcome oggetti richiamabili.Definire markup, attributi e styling in un unico posto garantisce coerenza in tutta l'applicazione. Quando importi e usi queste funzioni, qualsiasi modifica visiva o comportamentale si propaga automaticamente.
Questo approccio riduce il codice ripetuto, rendendo il tuo frontend facile da testare e rifattorizzare come qualsiasi modulo Python.
Per dimostrarlo, creiamo una pagina che mostra due semplici card.
La funzione
Cardaccetta due stringhe,titleebody, come argomenti e restituisce un elemento card con uno styling di base. Nella routehome, questo widget viene usato due volte senza duplicare il codice. Definiamo laCarduna sola volta e la riutilizziamo quando serve, assicurando markup e styling coerenti in tutta l'app.Creare widget UI in questo modo offre diversi vantaggi.
Uso avanzato
Questa sezione esplora tecniche avanzate in FastHTML, tra cui gestione dei form, validazione e pattern di feedback sugli errori. Sfruttando classi Python e componenti strutturati, puoi costruire form robusti e user-friendly mantenendo codice pulito e testabile.
Gestione dei form e validazione
FastHTML semplifica la gestione dei form generando automaticamente HTML a partire da classi Python e fornendo un data binding lineare per elaborare gli invii dei form.
Per esempio, considera il seguente codice.
Questo codice genera il seguente HTML per il form. FastHTML analizza automaticamente i dati del form nell'oggetto
Profile, supponendo nomi di campo compatibili. Sotto il cofano, ciò può basarsi su parsing in stile Starlette e su un layer di validazione personalizzato.Una volta inviato il form, FastHTML analizza i dati del form nell'oggetto
Profile. La routeprofilequindi restituisce una pagina di conferma, mostrando i valori inviati direttamente dall'oggettodata. Questo approccio semplifica la gestione dei form, riduce il boilerplate e garantisce un forte typing dei dati in tutta l'applicazione.È sempre una buona idea validare gli input del form. Aggiungi logica di validazione riscrivendo la route
/profilecome segue.Se
namemanca,emailmanca oageè negativo, l'utente riceve un messaggio di errore chiaro. Sollevando un'HTTPExceptioncon status code 400, l'applicazione comunica lo specifico errore di validazione, aiutando l'utente a correggere l'input prima di inviare di nuovo il form.Un modo più robusto di gestire dati mancanti o non validi è effettuare controlli di errore espliciti e fornire feedback user-friendly. Ad esempio, riscrivi il codice come segue.
Se l'utente salta un campo obbligatorio o fornisce un input non valido, vedrà il form renderizzato di nuovo con i valori inviati e gli opportuni messaggi di errore accanto a ciascun campo. Questo approccio migliora l'esperienza utente indicando chiaramente cosa va corretto.
Una volta compilati tutti i campi e inviato, otterrai una schermata simile alla seguente.
Autenticazione e gestione della sessione
Implementare i flussi di autenticazione
In FastHTML, i dati di sessione sono gestiti tramite l'oggetto
request.session, che si comporta come un dizionario Python. Puoi memorizzare dati nella sessione impostando coppie chiave-valore, ad esempiosession['user_id'] = 123. Per recuperare i dati di sessione, usaread (user_id = session.get('user_id')). Per cancellare tutti i dati di sessione, chiamasession.clear().Dietro le quinte, FastHTML serializza il dizionario di sessione in un cookie firmato, che persiste tra le richieste. Questo approccio ti permette di gestire autenticazione utente e stato di sessione usando pattern Python familiari.
Schema per costruire workflow di autenticazione
Per costruire un workflow di autenticazione, segui questi passaggi.
con unasecret_keyrobusta. Una volta configurato,request.sessionè disponibile in ogni handler.epassword_hash. Usa una funzione di hashing (ad es.hashlib,pbkdf2_hmac,bcrypt) per memorizzare e verificare le password.per mostrare un form di signup.* Usa POST /registerper validare l'input del form, fare l'hash della password, salvare il record utente, impostaresession['user_id']e reindirizzare a una pagina protetta o alla dashboard.per mostrare il form di login.* Usa POST /loginper verificare le credenziali. In caso di successo, scrivisession['user_id']e reindirizza; in caso di fallimento, renderizza di nuovo il form con un messaggio di errore.. Se l'utente non è autenticato, reindirizza a/login; altrimenti consenti l'accesso alla route richiesta., chiamasession.clear()` per rimuovere i dati di sessione e reindirizzare l'utente alla pagina di login o alla home.Integrazione con database
Un Object-Relational Mapper (ORM) mappa le classi alle tabelle del database, permettendoti di interrogare i dati usando oggetti nativi invece di SQL grezzo. Opzioni popolari includono SQLAlchemy e l'ORM di Django.
FastHTML ha un'interfaccia "simile a un ORM" che si integra con qualsiasi ORM o libreria di query Python compatibile con async. Di default usa SQLite ma può integrarsi con qualsiasi backend di database. Per esempio, considera il seguente codice.
In un'applicazione FastHTML, interroghi i dati nello strato di database che preferisci, quindi passi i risultati ai componenti FastHTML per il rendering. Ad esempio, dopo aver recuperato i record dal database, puoi iterarli in un route handler e costruire strutture HTML come tabelle, liste o card personalizzate.
Le best practice restano valide: seleziona solo i campi necessari, filtra e ordina a livello di database e pagina risultati di grandi dimensioni. FastHTML ti aiuta a concentrarti sulla costruzione di front-end puliti e dinamici lasciando la gestione dei dati agli strumenti migliori per il tuo progetto.
Strategie di ottimizzazione delle prestazioni
Ci sono diversi modi per ottenere i migliori risultati con FastHTML. Di seguito abbiamo raccolto alcuni consigli.
Meccanismi di caching
Il caching migliora le prestazioni evitando lavoro ridondante a diversi livelli dell'applicazione. A livello di browser e CDN, usa gli header di cache control per trattenere asset statici come immagini, script e fogli di stile.
Nel tuo framework web, puoi mettere in cache intere risposte di route o parti costose. All'interno della tua app FastHTML, metti in cache risposte di route intere o componenti costosi, garantendo che le richieste ripetute tornino rapidamente senza ri-interrogare il database o rigenerare template.
In Python, puoi implementare il caching a livello di funzione utilizzando decorator. Ad esempio, il decorator incorporato
functools.lru_cachepuò memorizzare i risultati di una funzione helper che recupera i dati utente. Per esempio, potresti usare questo decorator per mettere in cache le chiamate al database:Code di task asincrone
Le applicazioni web restano reattive delegando i task che richiedono tempo fuori dal ciclo della richiesta. Invece di bloccare il server mentre generi report, invii email o elabori dati, questi task vengono accodati ed eseguiti in background.
Con questo approccio, la tua applicazione invia una risposta immediata all'utente mentre worker, in processi o thread separati, elaborano i task in coda in modo asincrono.
FastHTML supporta l'esecuzione di task in background integrandosi con il
BackgroundTasksdi Starlette. Ecco un esempio che mostra come inviare un'email di benvenuto dopo la registrazione dell'utente.Applicazioni reali
FastHTML è un framework versatile che può alimentare un'ampia gamma di applicazioni web. Vediamo come potresti affrontare la costruzione di una piattaforma e-commerce e di una dashboard dati usando FastHTML.
Blueprint per una piattaforma e-commerce
Costruiamo una piattaforma ecommerce con FastHTML. Inizia modellando i tuoi dati principali come classi ORM o dataclass Python: prodotti, utenti e articoli del carrello.
Crea una pagina di elenco prodotti che iteri sui record. Per ogni prodotto, usa un componente Python riutilizzabile, come una
Card, per mostrare prodotto, immagine, nome, prezzo e un pulsante "Aggiungi al carrello". Questo pulsante include attributi HTMX comehx_postehx_target, che gli permettono di inviare una richiesta per aggiungere l'articolo al carrello in sessione dell'utente senza ricaricare l'intera pagina.Il carrello è memorizzato nel dizionario di
sessiondell'utente sul server. Nell'intestazione del sito, includi un componente riepilogo del carrello che si aggiorna dinamicamente con HTMX ogni volta che gli articoli vengono aggiunti o rimossi.La pagina del carrello legge i dati di sessione per renderizzare ciascun articolo insieme al totale complessivo. Offre anche un form di checkout collegato a una classe Python per la validazione. Quando l'utente invia il form, l'app crea un record d'ordine e svuota il carrello in sessione.
Implementazione di una dashboard dati
Una dashboard dati in FastHTML combina componenti Python con le tue sorgenti dati, usando HTMX per interattività e aggiornamenti in tempo reale. La tua logica backend (ad es. funzioni helper async, utility CRUD con cache o query ORM) recupera i dati necessari.
Da lì, progetti una pagina con widget riutilizzabili. Questi possono includere controlli di filtro (come menu a discesa, selettori di date o caselle di ricerca) per affinare le query, card KPI per mostrare metriche chiave, tabelle dati per elencare record o grafici incorporati per visualizzare trend e confronti.
Ogni widget è scritto come codice Python nativo, tipicamente un
Div,Tableo un componenteCardpersonalizzato. FastHTML trasforma automaticamente questi oggetti in HTML al momento della risposta.HTMX rende le dashboard interattive. Ad esempio, i widget di filtro possono usare
hx_getehx_postper richiedere dati filtrati al server, aggiornando dinamicamente tabelle o grafici senza richiedere un reload completo della pagina.Analisi comparativa con i framework tradizionali
FastHTML si distingue da framework tradizionali come Django e Flask semplificando sia lo sviluppo sia le prestazioni. Vediamo come si confronta su fattori chiave come tempi di setup, efficienza del codice e benchmark prestazionali.
Velocità di sviluppo
FastHTML ha due vantaggi chiave rispetto a framework come Django e Flask: tempi di setup ed efficienza del codice.
Tempo di setup
L'approccio "batteries-included" di Django richiede diversi passaggi prima di poter servire la prima pagina: installare il pacchetto, eseguire
django-admin startproject, configurare le impostazioni e definire un'app. Questo spesso comporta più file e molto boilerplate prima di scrivere logica reale.Flask è più snello. Dopo il
pip install, puoi scrivere un paio di route in un singolo file. Tuttavia, devi comunque configurare i template Jinja, le cartelle static e aggiungere JavaScript per l'interattività.Con FastHTML, il setup è minimo.
pip install python-fasthtml uvicorn.serve().Non serve un motore di template separato né la configurazione di una cartella static. Puoi iniziare a costruire subito.
Efficienza del codice
Con Django, anche una semplice pagina "Hello, world" richiede più file:
views.py,urls.py,settings.py,templates/hello.html, oltre all'impalcatura di ORM e admin.Flask semplifica il processo a un singolo file, ma devi comunque scrivere manualmente HTML nei template Jinja o in stringhe inline, e JavaScript per l'interattività.
FastHTML ti permette di definire la UI come oggetti Python, quindi non serve cambiare file o linguaggi. HTMX gestisce l'interattività in modo dichiarativo senza script personalizzati. Il risultato sono meno righe di codice, nessun template o pipeline di asset statici separati e un'unica superficie testabile per markup e comportamento.
Benchmark delle prestazioni
Studi di benchmark mostrano che i framework asincroni superano quelli sincroni sotto alta concorrenza. Ad esempio, in un confronto prestazionale tra Flask, Django, Quart e FastAPI, i framework asincroni (Quart e FastAPI) hanno gestito molte più richieste al secondo rispetto alle controparti sincrone.
Ciò è attribuito ai loro meccanismi di gestione non bloccante delle richieste, che consentono di gestire più richieste simultaneamente senza attendere il completamento delle operazioni di I/O.
Tabella di confronto
Per capire meglio come FastHTML si confronta con framework più affermati, la tabella seguente evidenzia le differenze chiave in termini di tempi di setup, efficienza del codice e caratteristiche prestazionali tra FastHTML, Flask e Django.
Feature
FastHTML
Flask
Django
Setup Time
Minimo: pip install, definisci route e componenti in un file, chiama serve()
Moderato: avvio rapido con un singolo file, ma richiede template Jinja e setup della cartella static
Lungo: richiede scaffolding del progetto, configurazione delle impostazioni, definizione delle app e più file
Template Engine
Non necessario—usa oggetti Python per l'HTML
Richiesto il motore di templating Jinja2 per le view
Usa i Template di Django con un linguaggio e una directory separati
Front-End Interactivity
Dichiarativa tramite HTMX, non serve JavaScript
JavaScript manuale tipicamente necessario per l'interattività
Richiede JavaScript per l'interattività, spesso con tool esterni
Code Efficiency
Alta: poco boilerplate, HTML pythonico, logica + UI unificate
Moderata: routing conciso ma l'HTML vive nei template, l'interattività necessita JS personalizzato
Bassa: logica, template e configurazione sono distribuiti in molti file
Performance (Concurrency)
Alta: basato su ASGI con supporto async, adatto ad alta concorrenza
Inferiore: basato su WSGI, gestione sincrona salvo estensioni async
Inferiore: basato su WSGI e sincrono di default; richiede setup aggiuntivo per il supporto async
Linee di codice per "Hello, World"
Pochissime righe in un file
Poche righe, ma richiede template o HTML inline
Più file tra view, URL, template e impostazioni
Conclusione
FastHTML offre un approccio nuovo e pythonico alla costruzione di applicazioni web, combinando la flessibilità degli oggetti Python con la potenza dell'esecuzione asincrona. Eliminando la necessità di file template separati, pipeline di asset statici e framework frontend, FastHTML snellisce lo sviluppo e ti permette di creare interfacce dinamiche e interattive in modo rapido ed efficiente.
Con HTMX per l'interattività, ASGI per le prestazioni e un'integrazione fluida con ORM compatibili con async, FastHTML è adatto a progetti web moderni—da piattaforme e-commerce a dashboard dati e oltre. Il setup minimo, il boilerplate ridotto e la codebase unificata lo rendono una scelta interessante per chi cerca un'alternativa leggera e produttiva ai framework tradizionali come Django e Flask.
Per chi è interessato a esplorare strumenti e approcci correlati allo sviluppo web in Python, le seguenti risorse offrono i prossimi passi consigliati.