Flask è un framework web leggero per Python che permette di creare siti dinamici, applicazioni web, backend e API partendo da un nucleo relativamente piccolo. Fornisce gli elementi essenziali per ricevere richieste HTTP, associarle al codice Python corretto e generare una risposta, lasciando allo sviluppatore maggiore libertà nella scelta di database, autenticazione, struttura del progetto e altri componenti.

È proprio questa caratteristica a spiegare perché venga spesso definito un micro-framework. “Micro” non significa però che sia adatto soltanto a piccoli esercizi: indica soprattutto che evita di imporre fin dall’inizio uno stack applicativo molto esteso.

Puoi creare un primo progetto in poche righe e, se l’applicazione cresce, organizzarla con package, Blueprint, Application Factory, estensioni, database, test e un’infrastruttura di produzione adeguata.

In questa guida vedremo come funziona Flask, come installarlo, come realizzare una prima applicazione, come passare da un singolo file a un progetto più strutturato e, soprattutto, quando questa libertà rappresenta un vantaggio rispetto a framework come Django o FastAPI.

Cos’è Flask e a cosa serve

Flask è un framework per lo sviluppo web server-side con Python.

Quando un browser, un’applicazione o un altro client invia una richiesta al server, il framework può determinare quale parte del codice deve gestirla, eseguire la logica necessaria e restituire una risposta.

Il percorso concettuale è questo:

client → richiesta HTTP → server → applicazione Python → risposta HTTP → client

Si colloca quindi nel backend, cioè nella parte dell’applicazione responsabile della logica eseguita sul server, dei dati, delle autorizzazioni, delle integrazioni e della costruzione delle risposte.

La documentazione ufficiale lo descrive come un framework WSGI leggero progettato per rendere semplice l’avvio di un progetto senza impedire la crescita verso applicazioni più complesse.

Perché Flask viene definito un micro-framework

La parola micro-framework può creare un equivoco.

Non significa che il software imponga applicazioni minuscole o che manchino strumenti per costruire progetti seri. Il termine riguarda soprattutto la scelta di mantenere intenzionalmente ridotto il core.

Il nucleo si concentra su routing, richieste e risposte, integrazione WSGI, rendering dei template attraverso Jinja, sessioni, gestione degli errori, configurazione, CLI e supporto alle estensioni.

Non integra invece obbligatoriamente un ORM specifico, un sistema amministrativo completo, un’architettura applicativa rigida o una soluzione unica per ogni problema.

Questa filosofia lascia molte decisioni allo sviluppatore.

Se devi collegare un database, per esempio, non sei costretto a utilizzare una particolare libreria solo perché hai scelto questo stack. Puoi selezionare lo strumento più adatto al progetto oppure aggiungere un’estensione che integri quella funzione.

È una differenza importante rispetto a framework più prescrittivi: riduce ciò che decide al posto tuo, ma aumenta ciò che devi decidere tu.

Cosa include il framework e cosa devi aggiungere

L’installazione porta con sé alcune dipendenze fondamentali. La documentazione sull’installazione indica tra i componenti principali:

ComponenteFunzione principale
Flaskframework applicativo
Werkzeuggestione WSGI, richieste, risposte e utility web
Jinjamotore per i template
MarkupSafeescaping sicuro dei contenuti usati nei template
ItsDangerousfirma dei dati, utilizzata anche per le sessioni
Clickcomandi da terminale e CLI
Blinkersistema di segnali

Per database, ORM, autenticazione avanzata, API più strutturate e altre funzioni puoi invece aggiungere librerie o estensioni.

La documentazione corrente consiglia di cercare le estensioni dedicate su PyPI. Non esiste quindi un catalogo obbligatorio di componenti “approvati” da seguire: ogni dipendenza va valutata per manutenzione, compatibilità, documentazione e adeguatezza al progetto.

Cosa puoi costruire con Flask

Il framework può essere usato per applicazioni molto diverse: siti con pagine renderizzate sul server, aree riservate, dashboard, pannelli interni, backend che comunicano con frontend JavaScript, servizi interni o endpoint JSON.

È adatto, tra gli altri scenari, a:

  • applicazioni web;
  • dashboard e strumenti aziendali;
  • backend per frontend separati;
  • API HTTP;
  • microservizi;
  • prototipi che devono evolvere.

La scelta non dovrebbe però dipendere soltanto da ciò che può fare. Un framework va valutato considerando anche complessità del dominio, dimensione del team, autenticazione, modello dei dati, necessità asincrone, deployment e manutenzione futura.

Come funziona Flask: dalla richiesta HTTP alla risposta

Per capire il meccanismo è più utile seguire una richiesta che memorizzare decoratori e metodi.

Immagina di aprire:

https://example.com/prodotti/42

Il client invia una richiesta HTTP al server. Il server che esegue l’applicazione la inoltra al codice Python attraverso l’interfaccia WSGI.

Il router confronta quindi il percorso richiesto con le route registrate.

Una route potrebbe essere:

@app.route("/prodotti/<int:id_prodotto>")
def prodotto(id_prodotto):
    ...

Se il percorso corrisponde, viene eseguita la funzione prodotto() passando il valore estratto dall’URL.

La funzione può interrogare un database, applicare regole di business, comunicare con un altro servizio oppure preparare dati per un template.

Il risultato viene infine trasformato in una risposta HTTP e restituito al client.

Schema del percorso di una richiesta HTTP dal routing alla view Python e alla risposta
Una richiesta viene associata a una route, elaborata dal codice Python e trasformata in una risposta HTTP.

In forma semplificata:

GET /prodotti/42
        ↓
routing
        ↓
funzione prodotto(42)
        ↓
logica + eventuali dati
        ↓
HTML / JSON / redirect / errore
        ↓
risposta HTTP

Questo modello è utile anche se stai studiando il lavoro del web developer: un framework non elimina il funzionamento di HTTP, routing, database e risposte. Fornisce strumenti per gestirli con meno codice ripetitivo e con convenzioni più affidabili.

Flask e WSGI

Flask è una applicazione WSGI.

WSGI, acronimo di Web Server Gateway Interface, definisce un’interfaccia standard tra applicazioni web Python e server capaci di eseguirle.

Questo livello permette di separare due responsabilità:

server WSGI → esecuzione e gestione delle richieste
applicazione → logica del progetto

Il server non deve conoscere le route del tuo ecommerce e il framework non deve implementare da zero tutta l’infrastruttura necessaria per ricevere traffico di produzione.

Se vuoi approfondire il livello precedente all’applicazione, nella guida dedicata trovi anche come funziona un web server.

Routing e view function

Una delle operazioni fondamentali consiste nell’associare un URL a una funzione Python.

Per esempio:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Benvenuto"

Il decoratore:

@app.route("/")

registra la route /.

Quando arriva una richiesta compatibile con quel percorso, viene eseguita la funzione home().

Possiamo creare anche una seconda route:

@app.route("/chi-siamo")
def chi_siamo():
    return "Pagina chi siamo"

oppure parti dinamiche:

@app.route("/utenti/<nome>")
def utente(nome):
    return f"Ciao {nome}"

Una richiesta verso:

/utenti/mario

passerà "mario" alla funzione.

Le route possono inoltre essere limitate a particolari metodi HTTP:

@app.route("/login", methods=["GET", "POST"])
def login():
    ...

Il routing collega quindi risorsa richiesta, metodo HTTP e codice applicativo.

Template Jinja e pagine dinamiche

Restituire direttamente una stringa HTML funziona per il primo test, ma diventa rapidamente scomodo.

Jinja permette di separare il markup dalla logica Python.

Puoi creare:

templates/
└── home.html

con:

<!doctype html>
<html lang="it">
<head>
    <meta charset="utf-8">
    <title>{{ titolo }}</title>
</head>
<body>
    <h1>{{ messaggio }}</h1>
</body>
</html>

e renderizzarlo dalla view:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template(
        "home.html",
        titolo="La mia applicazione",
        messaggio="Benvenuto"
    )

La logica Python rimane così separata dal markup della pagina.

È una distinzione semplice ma importante: quando il progetto cresce, mescolare query al database, HTML, validazione e logica di business nella stessa funzione produce codice difficile da modificare e testare.

Come installare Flask

Per iniziare ti servono Python, pip e un ambiente di sviluppo.

La serie 3.1.x supporta Python 3.9 e versioni successive. Per un nuovo progetto conviene comunque utilizzare una versione Python attuale e supportata, verificando anche la compatibilità delle altre dipendenze.

Crea un ambiente virtuale

Un ambiente virtuale mantiene isolate le librerie di ogni progetto.

Su macOS o Linux:

mkdir progetto-flask
cd progetto-flask
python3 -m venv .venv

poi:

source .venv/bin/activate

Su Windows:

mkdir progetto-flask
cd progetto-flask
py -3 -m venv .venv

e:

.venv\Scripts\activate

Usare un virtual environment evita che l’aggiornamento di una libreria per un progetto modifichi anche le dipendenze di altri software Python presenti sulla stessa macchina.

Installa il framework

Con l’ambiente virtuale attivo:

pip install Flask

A questo punto vengono installati il framework e le sue dipendenze principali.

Puoi controllare i package con:

pip list

Per verificare la versione installata:

pip show Flask

Creare la prima applicazione Flask

Creiamo un file:

app.py

con:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "<h1>La mia prima app</h1>"

La riga:

app = Flask(__name__)

crea l’oggetto applicazione.

__name__ aiuta il framework a determinare dove si trova il modulo e quindi dove cercare risorse come template e file statici.

Avvia ora il server di sviluppo:

flask --app app run

Durante lo sviluppo puoi usare:

flask --app app run --debug

Di default il progetto sarà normalmente raggiungibile su:

http://127.0.0.1:5000/

Aprendo quell’indirizzo nel browser vedrai il contenuto restituito dalla funzione home().

Cosa succede quando apri la pagina

Questo piccolo esempio contiene già quasi tutto il percorso fondamentale:

browser
  ↓
GET /
  ↓
server di sviluppo
  ↓
applicazione
  ↓
routing
  ↓
home()
  ↓
stringa HTML
  ↓
risposta HTTP
  ↓
browser

Capire questo flusso è più importante che imparare a memoria @app.route.

Quando in seguito aggiungerai database, autenticazione, servizi esterni o template, quelle componenti entreranno all’interno dello stesso ciclo richiesta-risposta.

Creare una route dinamica

Aggiungiamo:

@app.route("/ciao/<nome>")
def saluta(nome):
    return f"<h1>Ciao {nome}!</h1>"

Aprendo:

http://127.0.0.1:5000/ciao/Anna

il valore Anna viene estratto dal percorso e passato come argomento alla funzione.

Possiamo anche vincolare il tipo del parametro:

@app.route("/articoli/<int:id_articolo>")
def articolo(id_articolo):
    return f"Articolo numero {id_articolo}"

Una route come:

/articoli/15

verrà accettata perché 15 può essere convertito in intero.

Restituire JSON e creare un semplice endpoint API

Una route può restituire anche strutture serializzate come JSON.

Per esempio:

@app.route("/api/stato")
def stato():
    return {
        "status": "ok",
        "framework": "Flask"
    }

Il client riceverà una risposta JSON.

Questo rende possibile usare la stessa base anche per un backend che espone API.

Va però fatta una distinzione: poter costruire API non significa essere un framework API-first. Se il progetto ruota quasi interamente attorno a API tipizzate, validazione automatica degli input e schema OpenAPI, è utile confrontare questa soluzione con strumenti nati specificamente per quel lavoro.

Come strutturare un progetto Flask oltre il primo esempio

Un’applicazione da venti righe può vivere tranquillamente in app.py.

Il problema nasce quando nello stesso file cominciano ad accumularsi decine di route, query al database, configurazioni, autenticazione, modelli, form, integrazioni e gestione degli errori.

A quel punto il limite non è il framework. È l’architettura del progetto.

Da un singolo file a un package Python

Una struttura più realistica potrebbe diventare:

progetto/
├── app/
│   ├── __init__.py
│   ├── routes.py
│   ├── services.py
│   ├── templates/
│   └── static/
├── tests/
├── .venv/
└── pyproject.toml

Non esiste una struttura universale corretta per ogni applicazione. L’obiettivo è creare confini comprensibili tra responsabilità diverse.

Una route, per esempio, non dovrebbe diventare automaticamente il luogo in cui vengono gestiti routing, business logic, accesso al database, invio email e formattazione della risposta.

Più responsabilità concentri nello stesso punto, più il codice diventa difficile da testare e riutilizzare.

Application Factory

Quando il progetto cresce, uno dei pattern più utili è l’Application Factory.

Invece di creare l’applicazione direttamente al caricamento del modulo:

app = Flask(__name__)

puoi racchiudere la creazione in una funzione:

from flask import Flask

def create_app():
    app = Flask(__name__)

    # configurazione
    # estensioni
    # blueprint

    return app

La documentazione sulle Application Factory evidenzia un vantaggio concreto: puoi creare più istanze con configurazioni differenti.

È particolarmente utile nei test oppure quando vuoi separare ambienti di sviluppo, staging e produzione.

Il pattern riduce inoltre il rischio di legare troppo presto estensioni e componenti a un’unica istanza globale.

Blueprint: dividere l’applicazione in componenti

I Blueprint permettono di organizzare gruppi di route e altre funzionalità in componenti distinti.

Supponiamo di avere una sezione amministrativa:

from flask import Blueprint

admin = Blueprint(
    "admin",
    __name__,
    url_prefix="/admin"
)

@admin.route("/")
def dashboard():
    return "Dashboard amministrativa"

e di registrarla nell’applicazione:

app.register_blueprint(admin)

La route sarà disponibile su:

/admin/

La documentazione ufficiale sui Blueprint li indica come uno degli strumenti per suddividere applicazioni più grandi in componenti.

Un Blueprint non è però un’applicazione indipendente: registra operazioni su un’app esistente e ne condivide la configurazione.

Database e ORM non sono imposti

Uno degli aspetti più caratteristici di questo ecosistema è l’assenza di un singolo sistema di persistenza obbligatorio.

Puoi lavorare direttamente con un driver, usare SQLAlchemy oppure scegliere altri strumenti a seconda del database e dell’architettura.

Per un’applicazione reale la scelta del database non dovrebbe essere fatta pensando soltanto a “quale tutorial è più semplice”.

Devi considerare struttura dei dati, relazioni, concorrenza, transazioni, query previste, migrazioni, disponibilità operativa e competenze del team.

Se il progetto richiede un database relazionale completo, può avere senso valutare tecnologie come PostgreSQL invece di considerare la persistenza un semplice dettaglio del framework.

Estensioni Flask: utili, ma non sono magia

L’ecosistema mette a disposizione estensioni che aggiungono funzionalità non presenti nel core.

La documentazione ufficiale sulle estensioni cita come esempi connessioni ai database, invio di email e framework aggiuntivi per particolari tipi di applicazione.

Questo approccio è potente perché permette di comporre lo stack.

Ha però una conseguenza pratica: ogni estensione diventa una dipendenza che devi valutare e mantenere.

Prima di aggiungerne una controlla documentazione, compatibilità, manutenzione, issue rilevanti e necessità reale.

Installare automaticamente un’estensione per ogni problema può portare a un progetto apparentemente semplice ma composto da molte dipendenze poco comprese.

Quando l’integrazione richiesta è piccola, una libreria Python generica o poche righe di codice ben isolate possono essere più sostenibili.

Flask in produzione: flask run non basta

Uno degli errori più comuni nei primi tutorial è fermarsi quando l’applicazione funziona su:

localhost:5000

Questo dimostra che il codice gira sul computer dello sviluppatore. Non dimostra che il progetto sia pronto per essere esposto a utenti reali.

La documentazione ufficiale sul deployment è chiara: il server di sviluppo non deve essere utilizzato in produzione.

Non è progettato per fornire sicurezza, stabilità ed efficienza richieste da un ambiente reale.

Server WSGI e reverse proxy

In produzione l’architettura può assumere, per esempio, questa forma:

Internet
   ↓
reverse proxy / HTTP server
   ↓
server WSGI
   ↓
applicazione Python
   ↓
servizi e database

Tra i server WSGI citati dalla documentazione trovi Gunicorn, Waitress, mod_wsgi e uWSGI.

La scelta dipende però dal sistema operativo, dal modello di deployment e dai requisiti del progetto.

Un reverse proxy davanti all’applicazione può inoltre gestire TLS, connessioni HTTP, header, file statici o distribuzione del traffico.

Non devi necessariamente assemblare manualmente ogni componente: puoi distribuire il software anche attraverso una piattaforma gestita.

Deploy su una piattaforma PaaS

Una PaaS, Platform as a Service, astrae parte dell’infrastruttura necessaria a eseguire l’applicazione.

Invece di configurare manualmente server, networking e parte della piattaforma operativa, puoi concentrarti maggiormente sul codice e sulla configurazione.

Questo non elimina le responsabilità applicative: devi comunque gestire dipendenze, segreti, database, log, configurazione, sicurezza e scalabilità.

Riduce però la quantità di infrastruttura che devi amministrare direttamente.

Quando entra in gioco Docker

Un’altra possibilità è distribuire l’applicazione dentro un container.

Docker permette di impacchettare codice, runtime e dipendenze in un ambiente riproducibile.

È utile soprattutto quando vuoi ridurre le differenze tra computer dello sviluppatore, pipeline CI/CD e server.

Docker però non rende automaticamente un’app pronta per la produzione.

All’interno del container devi comunque definire correttamente il processo di esecuzione, gestire configurazione e segreti e scegliere l’architettura di rete e persistenza appropriata.

Il container è una modalità di packaging ed esecuzione. Non sostituisce l’architettura del progetto.

Flask e async: cosa supporta davvero

È possibile definire alcune view con async def, ma qui è importante evitare una semplificazione comune.

Il framework rimane basato su WSGI.

Con il supporto async installato puoi scrivere:

@app.route("/dati")
async def dati():
    risultato = await recupera_dati()
    return risultato

Questo può essere utile quando una singola richiesta deve attendere più operazioni I/O concorrenti, come chiamate HTTP o query asincrone.

Non significa però trasformare automaticamente l’applicazione in un sistema ASGI capace di moltiplicare il numero di richieste concorrenti gestite dallo stesso worker.

Una view async continua a occupare un worker

La documentazione su async e await spiega che ogni richiesta a una view asincrona continua a impegnare un worker per l’intero ciclo request/response.

Viene creato un event loop per eseguire la coroutine, ma il modello di concorrenza complessivo resta legato alla natura WSGI.

L’async può quindi migliorare particolari operazioni I/O all’interno della singola richiesta.

Non è corretto concludere:

async = più richieste simultanee = applicazione più veloce

La realtà dipende dal workload.

Per operazioni CPU-bound async non risolve il problema. Per I/O concorrente può invece ridurre il tempo passato ad attendere operazioni indipendenti.

Background task: non usare asyncio.create_task() come scorciatoia

C’è un secondo limite importante.

Con il normale modello async, l’event loop utilizzato per la view termina quando la richiesta ha concluso l’esecuzione. Eventuali task ancora incompleti possono quindi essere cancellati.

Per lavori che devono continuare dopo la risposta — invio massivo di email, elaborazioni pesanti, generazione di report o altri job — è normalmente più appropriato utilizzare una task queue o un sistema dedicato ai background job.

In questo modo separi due responsabilità:

request web → risposta relativamente rapida
job asincrono → elaborazione indipendente

Quando un framework ASGI può essere più naturale

Se l’applicazione è prevalentemente asincrona, gestisce molte connessioni concorrenti, WebSocket o richieste lunghe, il modello WSGI potrebbe non essere la scelta più naturale.

La stessa documentazione suggerisce di considerare Quart, una reimplementazione dell’API compatibile con ASGI, quando la codebase è principalmente async.

Questo non rende Flask obsoleto.

Significa che la scelta del framework deve partire dal modello operativo dell’applicazione, non dalla familiarità con la sintassi.

Flask vs Django vs FastAPI: quale scegliere

Flask, Django e FastAPI appartengono allo stesso ecosistema Python, ma non risolvono esattamente lo stesso problema nello stesso modo.

Ridurre il confronto a “qual è il migliore?” produce quasi sempre una risposta poco utile.

Conviene confrontare ciò che ciascuno decide al posto tuo.

CriterioFlaskDjangoFastAPI
Filosofiacore leggero e componibileframework molto integratoframework orientato principalmente alle API
Routing
Template server-sideJinjasistema template integratopossibile, ma non centrale
ORM inclusonono
Admin integratonono
Autenticazione completa integratanono
Validazione API basata sui type hintnon centrale nel corenon centrale nel coreelemento fondamentale
OpenAPI automaticorichiede strumenti aggiuntivirichiede strumenti aggiuntivi
Async-firstno, architettura WSGIsupporto async in più partisì, orientato ad ASGI
Libertà architetturale inizialealtaminore, più convenzionialta nel dominio API
Setup iniziale minimomolto ridottopiù strutturatomolto ridotto per API

La tabella non indica un vincitore assoluto. Mostra dove si trova la complessità.

Con Flask molte decisioni arrivano dopo.

Con Django molte sono già integrate.

Con FastAPI numerose convenzioni ruotano attorno alla definizione e validazione di API.

Quando scegliere Flask

È una scelta particolarmente sensata se vuoi un backend Python leggero, controllo sullo stack, possibilità di introdurre componenti gradualmente o un servizio web che non richieda subito un framework molto esteso.

Può essere utile anche per imparare più direttamente il rapporto tra routing, HTTP, view e risposta.

Il vantaggio maggiore è la bassa quantità di struttura imposta all’inizio.

Questo vantaggio diminuisce quando il progetto richiede molte componenti che un framework più integrato avrebbe già fornito e coordinato.

Quando Django può ridurre più complessità

Django segue una filosofia diversa.

Integra una quantità molto maggiore di infrastruttura applicativa, tra cui ORM, autenticazione, migrazioni, sistema amministrativo e numerosi strumenti per problemi comuni nello sviluppo web.

Se sai già che il progetto necessita di molti modelli relazionali, gestione utenti, permessi, backoffice, form e convenzioni condivise da un team, l’approccio più strutturato può eliminare molte decisioni che con uno stack più minimale dovresti prendere e mantenere separatamente.

La maggiore quantità di framework non è quindi automaticamente uno svantaggio.

Se coincide con le esigenze del progetto, può ridurre sensibilmente il numero di integrazioni da progettare.

Quando FastAPI è più naturale

FastAPI nasce con un forte orientamento alla costruzione di API.

Utilizza i type hint Python per ricavare informazioni sui parametri, validare dati e costruire automaticamente lo schema OpenAPI.

Questo rende particolarmente naturale scrivere endpoint come:

@app.get("/prodotti/{id_prodotto}")
async def prodotto(id_prodotto: int):
    ...

e ottenere dallo stesso contratto buona parte della validazione e della documentazione dell’API.

Se devi costruire soprattutto API JSON, backend per frontend separati, integrazioni machine-to-machine, servizi con uso intenso di I/O asincrono o sistemi in cui OpenAPI è centrale, può partire da un modello più vicino al problema.

La domanda corretta non è quindi quale framework abbia più funzionalità, ma quanto lavoro vuoi comporre autonomamente e quanto vuoi ricevere già coordinato.

Vantaggi e limiti di Flask nei progetti reali

La caratteristica che rende questo framework attraente è anche quella che può creare problemi: la libertà.

Il vantaggio: parti con ciò che serve davvero

Puoi realizzare il primo percorso funzionante con pochissimo codice.

Non devi configurare un ORM se l’applicazione non usa un database, né adottare un pannello amministrativo se non ti serve.

Questo riduce la quantità di concetti da affrontare all’inizio e permette di aggiungere complessità gradualmente.

Il limite: qualcuno deve prendere le decisioni mancanti

Quando il progetto cresce, iniziano però domande alle quali il core non fornisce deliberatamente una risposta unica.

Quale ORM usiamo? Come organizziamo servizi e repository? Come gestiamo le migrazioni? Quale sistema di autenticazione adottiamo? Come validiamo input complessi? Come eseguiamo job in background? Come monitoriamo l’applicazione?

La libertà permette di scegliere.

Ma poter scegliere non significa che una scelta non sia necessaria.

In un team esperto questa flessibilità è spesso utile.

In un progetto che necessita di convenzioni forti o coinvolge sviluppatori meno esperti può invece produrre architetture incoerenti, soprattutto quando ogni problema viene risolto aggiungendo una nuova estensione.

Semplice da iniziare non significa semplice da portare ovunque

Scrivere:

@app.route("/")
def home():
    return "Hello"

è semplice.

Costruire un’applicazione con autenticazione, transazioni, caching, code, sicurezza, osservabilità, test e deploy affidabile è un problema molto più ampio.

Non è una contraddizione.

Il framework semplifica una parte dello sviluppo web. Non elimina la complessità intrinseca del software che stai costruendo.

Il criterio più utile è quindi questo: non chiederti quanto è breve il primo tutorial, ma quanto la filosofia del framework resta adatta quando introduci i requisiti reali del progetto.

Errori da evitare quando inizi con Flask

Usare il server di sviluppo in produzione

flask run è uno strumento di sviluppo.

Per l’ambiente pubblico usa un deployment progettato per quel contesto.

Mettere tutta l’applicazione in un unico file

Per un tutorial va bene.

Quando route, modelli e servizi aumentano, separare responsabilità diventa necessario per mantenere il progetto leggibile.

Installare estensioni senza valutarle

Un’estensione risolve rapidamente un problema, ma diventa parte del software che dovrai aggiornare e mantenere.

Aggiungila perché riduce davvero complessità, non perché compare per prima in un tutorial.

Confondere il framework con Python

Flask è uno strumento costruito sopra Python.

Se non conosci variabili, funzioni, moduli, eccezioni, classi e ambienti virtuali, parte della difficoltà che incontrerai non dipenderà dal framework.

Imparare contemporaneamente Python, HTTP, HTML, database e sviluppo web è possibile, ma rende più difficile capire quale livello stia causando un errore.

Sceglierlo solo perché ha meno codice iniziale

La quantità di codice del primo esempio è un criterio debole.

Per scegliere un framework devi guardare il progetto che vuoi avere fra sei mesi, non soltanto il file che riesci a creare nei primi dieci minuti.

Domande frequenti su Flask

Flask è un framework frontend o backend?

È principalmente un framework backend.

Il codice Python viene eseguito lato server. Puoi generare pagine HTML con Jinja oppure fornire dati a un frontend separato.

HTML, CSS e JavaScript continuano invece a essere gestiti nel contesto del browser.

Flask può creare API REST?

Sì.

Puoi definire route per diversi metodi HTTP e restituire risposte JSON, quindi è possibile costruire API REST.

Per API complesse potresti però aggiungere librerie per validazione, serializzazione, documentazione OpenAPI e autenticazione oppure scegliere un framework specificamente orientato a questo lavoro.

Flask è adatto anche a progetti grandi?

Può esserlo.

Blueprint e Application Factory consentono di organizzare progetti articolati e non esiste un limite concettuale alla dimensione dell’applicazione.

La domanda più utile è però: quanto dell’infrastruttura di cui avrai bisogno vuoi progettare e integrare autonomamente?

In un’applicazione grande la flessibilità può essere un vantaggio per un team con architettura e convenzioni chiare, ma può diventare un costo se molte funzionalità devono essere assemblate singolarmente senza una strategia coerente.

Bisogna conoscere Python prima di usare Flask?

Non serve essere sviluppatori Python avanzati per iniziare, ma una conoscenza di base del linguaggio rende l’apprendimento molto più efficace.

Dovresti comprendere almeno variabili, funzioni, import, moduli, condizioni, strutture dati, eccezioni, package e ambienti virtuali.

Più il progetto cresce, più diventano importanti anche classi, typing, testing, packaging e gestione delle dipendenze.

Flask include un database?

No.

Non impone un particolare database o ORM.

Puoi scegliere direttamente una libreria per il database, utilizzare un ORM come SQLAlchemy o adottare un’estensione che integri gli strumenti necessari.

Flask è asincrono?

Supporta async def e await in determinate parti dell’applicazione, ma rimane un framework WSGI.

Una view asincrona continua normalmente a occupare un worker per la durata della richiesta.

Se l’architettura dipende fortemente da WebSocket, molte connessioni concorrenti o un modello async-first, può essere preferibile valutare una soluzione ASGI.

Conclusione

Flask è una scelta interessante quando vuoi sviluppare con Python senza partire da un framework che decida in anticipo gran parte dell’architettura.

Il suo punto di forza non è semplicemente essere “piccolo”. È offrire un nucleo web comprensibile e componibile, dal quale puoi aggiungere soltanto ciò che il progetto richiede.

Per imparare lo sviluppo backend questo approccio ha anche un vantaggio didattico: routing, richieste, risposte, template, server e database rimangono abbastanza visibili da aiutarti a capire cosa stia realmente succedendo.

La libertà ha però un costo.

Quando l’applicazione cresce, dovrai scegliere come strutturare codice, persistenza, autenticazione, API, background job e deployment. Se questi problemi costituiscono già gran parte del progetto, un framework più integrato come Django o più specializzato sulle API come FastAPI può ridurre il lavoro necessario.

Sceglierei Flask quando controllo e composizione dello stack sono vantaggi reali; sceglierei altro quando il progetto beneficia maggiormente di convenzioni e componenti già coordinati.

È una differenza più importante del numero di righe necessarie per stampare “Hello World”.