requirements.txt: congelare e ripristinare i pacchetti del venv
Come salvare i pacchetti di un venv con pip freeze e ricrearli con pip install -r su un altro PC, e perché il file ha più righe di quelle che hai installato.
Copi lo script sul PC di un collega, lo avvii e compare ModuleNotFoundError: la cartella è arrivata, i pacchetti no. Stanno nella .venv, che non si copia, come spiega la guida agli ambienti virtuali Python (venv) in 5 minuti. La soluzione è un file di testo, requirements.txt, con l’elenco dei pacchetti e delle versioni: lo generi con python -m pip freeze e lo ripristini con python -m pip install -r.
La risposta breve: con la .venv attiva lanci python -m pip freeze > requirements.txt; nella cartella di destinazione crei una .venv nuova e lanci python -m pip install -r requirements.txt. Nella prova ho installato solo due librerie, requests e tabulate, e il file è uscito con sei righe, perché requests si porta dietro altri quattro pacchetti. Il ripristino in una cartella vuota ha restituito esattamente lo stesso elenco.
ℹ️ Nota / Prerequisito operativo: ti serve una
.venvgià creata e attivata. Su Windows i comandi sono per il Prompt dei comandi (se preferisci PowerShell e l’attivazione viene bloccata, leggi PowerShell Execution Policy e Activate.ps1: errori tipici su Windows); su macOS e Linux usapython3solo per creare l’ambiente, perché una volta attivatopythonpunta al Python della.venv.
Che cosa contiene il file
pip freeze legge i pacchetti installati nell’ambiente attivo e li stampa nel formato nome==versione, uno per riga. Nella prova ho creato una cartella fatture con la sua .venv e ho installato le due librerie. L’ultima riga dell’installazione diceva:
Successfully installed certifi-2026.10.23 charset_normalizer-3.5.2 idna-3.20 requests-2.34.2 tabulate-0.10.0 urllib3-2.8.0
Due pacchetti richiesti, sei installati: requests dipende da certifi, charset_normalizer, idna e urllib3, e pip li ha aggiunti da solo. Il freeze li elenca tutti:
certifi==2026.10.23
charset-normalizer==3.5.2
idna==3.20
requests==2.34.2
tabulate==0.10.0
urllib3==2.8.0
L’ordine è alfabetico, non quello di installazione. Nota anche che charset_normalizer nel messaggio di installazione compare come charset-normalizer nel freeze: l’elenco usa il trattino, ma i due nomi indicano lo stesso pacchetto.
Manca una riga: pip. Nella .venv c’è (python -m pip list mostrava pip 25.1.1), ma pip freeze salta pip stesso; con l’opzione --all compare anche lui, come pip==25.1.1.
requests. Screenshot: ai riparoCongelare: il comando nel posto giusto
Con la .venv attiva, dalla cartella del progetto, su Windows (Prompt dei comandi):
python -m pip freeze > requirements.txt
Su macOS e Linux il comando è identico:
python -m pip freeze > requirements.txt
Il simbolo > manda l’output nel file invece che a schermo e sovrascrive il file se esiste già. Dopo un nuovo pip install è quello che vuoi, un elenco aggiornato; se però il file conteneva righe scritte a mano o commenti, li perdi.
💡 Consiglio pratico — Controlla l’ambiente prima di congelare: lancia
python -c "import sys; print(sys.prefix)"e verifica che il percorso finisca con.venv. Fuori dalla.venv, su Debian 13,python3 -m pip freezeha stampato 45 righe di pacchetti di sistema: avresti salvato nel file un ambiente che non è il tuo.
Ripristinare in una cartella nuova
Per simulare il PC del collega ho copiato in una cartella vuota, fatture-nuovo, solo requirements.txt: niente .venv. Una .venv appena creata contiene soltanto pip, e infatti import requests rispondeva:
ModuleNotFoundError: No module named 'requests'
requirements.txt è la lista del tuo progetto. Foto: Vlada Karpovich · PexelsLa procedura, su Windows (Prompt dei comandi), dalla cartella con il file:
python -m venv .venv --prompt .
.venv\Scripts\activate.bat
python -m pip install -r requirements.txt
Su macOS e Linux:
python3 -m venv .venv --prompt .
source .venv/bin/activate
python -m pip install -r requirements.txt
Ho eseguito la prova su Debian; i comandi per Windows e macOS sono quelli indicati dalla documentazione di venv e non li ho lanciati. Su Debian l’ultimo comando ha chiuso con la stessa riga dell’installazione originale, con le sei versioni identiche:
Successfully installed certifi-2026.10.23 charset-normalizer-3.5.2 idna-3.20 requests-2.34.2 tabulate-0.10.0 urllib3-2.8.0
Poi ho lanciato un nuovo pip freeze nella cartella ripristinata e l’ho confrontato con il file di partenza usando diff: nessuna differenza. Il file ha fatto il suo lavoro: stessi pacchetti, stesse versioni.
Elenco minimo a mano o elenco congelato?
Il file non deve per forza nascere da pip freeze: puoi scriverlo a mano con i soli pacchetti che usi. Nella prova ho provato anche questa strada, con un file di due righe, requests e tabulate, senza versioni. L’installazione ha portato gli stessi sei pacchetti, e pip freeze ha elencato sei righe.
| Tipo di file | Per uno script piccolo | Cosa devi sapere |
|---|---|---|
Congelato con pip freeze |
Consigliato | Fissa ogni versione, anche quelle delle dipendenze: ricrei l’ambiente com’era. È più lungo e non distingue ciò che hai scelto tu da ciò che è arrivato di riflesso. |
| Scritto a mano, senza versioni | Possibile | Leggibile in un secondo. Installa le versioni disponibili quel giorno, quindi tra sei mesi l’ambiente potrebbe non coincidere con quello in cui lo script funzionava. |
| Misto: poche versioni fissate a mano | Possibile | Fissi solo ciò che conta, per esempio tabulate==0.9.0; il resto resta libero. |
Il caso misto funziona come previsto. Con un file di due righe, requests e tabulate==0.9.0, pip ha installato proprio tabulate-0.9.0, anche se la versione più recente su PyPI era la 0.10.0, e il freeze riportava tabulate==0.9.0.
Per gli script di ai riparo ti consiglio la strada più semplice: congela, salva il file accanto allo script e rigeneralo quando cambi qualcosa. Un elenco minimo a mano ha senso se il progetto cresce e vuoi capire quali librerie hai scelto davvero.
Tenere il file aggiornato
Il file è una fotografia: non si aggiorna da solo. Dopo ogni pip install o pip uninstall riesegui il freeze nello stesso ambiente. Se il progetto è su Git, requirements.txt va versionato insieme al codice; la cartella .venv no, come ricorda la guida su come organizzare più .venv senza confonderti.
Errori tipici
ERROR: Could not open requirements file: [Errno 2] No such file or directory: 'requirement.txt'→ il nome è sbagliato (manca la «s») oppure sei nella cartella sbagliata: scrivendo il nome giusto da un’altra cartella ho ottenuto lo stesso messaggio, con'requirements.txt'→ controlla il nome, posizionati dove si trova il file o scrivi il percorso completo dopo-r.ERROR: No matching distribution found for tabulate==9.9.9→ hai fissato una versione che non esiste. Sopra questa riga pip stampa l’elenco di quelle disponibili (…0.9.0, 0.10.0) → correggi la versione nel file con una di quell’elenco.ModuleNotFoundErrordopo aver copiato il progetto → hai copiato il codice ma non hai ricreato la.venv, oppure l’ambiente non è attivo → crea la.venv, attivala e lanciapython -m pip install -r requirements.txt.- Il file ha decine di righe che non riconosci → hai congelato fuori dalla
.venve hai salvato i pacchetti di sistema → attiva la.venv, verifica consys.prefixe rilancia il freeze. - Su Linux Debian:
error: externally-managed-environmentdurantepip install -r→ stai installando fuori da un ambiente virtuale; l’ho riprodotto lanciandopython3 -m pip install -r requirements.txtsenza.venvattiva → crea e attiva una.venv(il motivo è spiegato inexternally-managed-environmentsu Linux).
Domande Frequenti (FAQ)
Posso lanciare pip freeze senza attivare la .venv?
Il comando funziona, ma descrive l’ambiente sbagliato: su Debian 13 ha elencato 45 pacchetti di sistema invece dei tuoi. Prima di congelare controlla sys.prefix, oppure chiama il Python della .venv per percorso: su Linux, nella prova, .venv/bin/python -m pip freeze ha elencato i pacchetti dell’ambiente senza attivarlo (su Windows il percorso è .venv\Scripts\python.exe, che non ho provato).
Perché pip non compare nel file?
pip freeze salta pip stesso. Se lo vuoi nel file aggiungi --all, ma di solito non serve: una .venv nuova ha già il suo pip.
Che cosa significa == in requests==2.34.2?
Significa «esattamente questa versione». Con python -m pip install -r requirements.txt pip installa proprio quella; se non esiste, si ferma con No matching distribution found.
requirements.txt si può usare tra sistemi operativi diversi?
Il file è solo testo, quindi lo puoi copiare dove vuoi. Non ho provato il passaggio tra Linux, macOS e Windows: i pacchetti di questa prova sono scritti in puro Python, ma altre librerie hanno componenti diverse per ogni sistema. Se il ripristino dà errore, rigenera il file sul sistema che usi.
Posso scrivere commenti dentro requirements.txt?
Sì. Nella prova ho usato un file con una riga che iniziava con #, una riga vuota e un commento dopo una versione (tabulate==0.9.0 # tabella nel report): pip li ha ignorati e ha installato le sei librerie. Ricorda però che un nuovo pip freeze > requirements.txt cancella i commenti.
Posso chiamare il file in un altro modo?
Sì, pip legge il nome che scrivi dopo -r. requirements.txt resta il nome che chiunque riconosce subito, quindi conviene non cambiarlo senza motivo.
Dal progetto al file, e ritorno
Il ciclo è corto: installi dentro la .venv, congeli, copi il file con il progetto; chi lo riceve crea una .venv vuota e installa dal file. Se vuoi ripassare creazione e attivazione dell’ambiente, c’è la guida agli ambienti virtuali Python (venv) in 5 minuti. Se lavori su Linux e il ripristino si ferma con un errore in rosso, leggi externally-managed-environment su Linux. Se ti serve uno script già pronto per un tuo progetto, con il suo ambiente e il suo requirements.txt, è il tipo di lavoro che realizzo su richiesta.