12. Ambienti Virtuali e Pacchetti
*********************************


12.1. Introduzione
==================

Le applicazioni Python spesso utilizzano pacchetti e moduli che non
fanno parte della libreria standard. Le applicazioni a volte
necessitano una versione specifica di una libreria, perché
l'applicazione potrebbe richiedere che un bug particolare sia stato
risolto o l'applicazione potrebbe essere stata scritta utilizzando una
versione obsoleta dell'interfaccia della libreria.

Questo significa che potrebbe non essere possibile per una singola
installazione di Python soddisfare i requisiti di ogni applicazione.
Se l'applicazione A necessita della versione 1.0 di un particolare
modulo ma l'applicazione B necessita della versione 2.0, allora i
requisiti sono in conflitto e l'installazione della versione 1.0 o 2.0
lascerà una delle applicazioni impossibilitata a funzionare.

La soluzione a questo problema è creare un *virtual environment*, un
albero di directory auto-contenuto che contiene un'installazione di
Python per una particolare versione di Python, più un numero di
pacchetti aggiuntivi.

Differenti applicazioni possono quindi utilizzare differenti ambienti
virtuali. Per risolvere l'esempio precedente di requisiti in
conflitto, l'applicazione A può avere il suo proprio ambiente virtuale
con la versione 1.0 installata mentre l'applicazione B ha un altro
ambiente virtuale con la versione 2.0. Se l'applicazione B richiede
che una libreria venga aggiornata alla versione 3.0, questo non
influenzerà l'ambiente dell'applicazione A.


12.2. Creazione di Ambienti Virtuali
====================================

Il modulo utilizzato per creare e gestire ambienti virtuali si chiama
"venv". "venv" installerà la versione di Python dalla quale il comando
è stato eseguito (come riportato dall'opzione "--version"). Per
esempio, eseguendo il comando con "python3.12" verrà installata la
versione 3.12.

Per creare un ambiente virtuale, decidi una directory dove vuoi
posizionarlo ed esegui il modulo "venv" come script con il percorso
della directory:

   python -m venv tutorial-env

Questo creerà la directory "tutorial-env" se non esiste, e creerà
anche directory all'interno contenenti una copia dell'interprete
Python e vari file di supporto.

Una posizione comune per una directory di ambiente virtuale è ".venv".
Questo nome mantiene la directory generalmente nascosta nella tua
shell e quindi fuori mano, dando anche un nome che spiega il motivo
dell'esistenza della directory. Previene anche conflitti con file di
definizione di variabili d'ambiente ".env" che alcuni strumenti
supportano.

Una volta creato un ambiente virtuale, puoi attivarlo.

Su Windows, esegui:

   tutorial-env\Scripts\activate

Su Unix o MacOS, esegui:

   source tutorial-env/bin/activate

(Questo script è scritto per la shell bash. Se utilizzi le shell
**csh** o **fish**, ci sono script alternativi "activate.csh" e
"activate.fish" che dovresti utilizzare.)

Attivare l'ambiente virtuale cambierà il prompt della tua shell per
mostrare quale ambiente virtuale stai utilizzando, e modificherà
l'ambiente in modo che eseguire "python" ti fornirà quella versione e
installazione particolare di Python. Per esempio:

   $ source ~/envs/tutorial-env/bin/activate
   (tutorial-env) $ python
   Python 3.5.1 (default, May  6 2016, 10:59:36)
     ...
   >>> import sys
   >>> sys.path
   ['', '/usr/local/lib/python35.zip', ...,
   '~/envs/tutorial-env/lib/python3.5/site-packages']
   >>>

Per disattivare un ambiente virtuale, scrivi:

   deactivate

nel terminale.


12.3. Gestione dei Pacchetti con pip
====================================

Puoi installare, aggiornare e rimuovere pacchetti utilizzando un
programma chiamato **pip**. Per impostazione predefinita "pip"
installerà pacchetti dal Python Package Index. Puoi sfogliare il
Python Package Index andando sul sito web con il tuo browser.

"pip" ha un certo numero di sottocomandi: "install", "uninstall",
"freeze", etc. (Consulta la guida Installing Python Modules per la
documentazione completa su "pip".)

Puoi installare l'ultima versione di un pacchetto specificando il nome
del pacchetto:

   (tutorial-env) $ python -m pip install novas
   Collecting novas
     Downloading novas-3.1.1.3.tar.gz (136kB)
   Installing collected packages: novas
     Running setup.py install for novas
   Successfully installed novas-3.1.1.3

Puoi anche installare una versione specifica di un pacchetto fornendo
il nome del pacchetto seguito da "==" e dal numero di versione:

   (tutorial-env) $ python -m pip install requests==2.6.0
   Collecting requests==2.6.0
     Using cached requests-2.6.0-py2.py3-none-any.whl
   Installing collected packages: requests
   Successfully installed requests-2.6.0

Se esegui nuovamente questo comando, "pip" noterà che la versione
richiesta è già installata e non farà nulla. Puoi fornire un numero di
versione diverso per ottenere quella versione, oppure puoi eseguire
"python -m pip install --upgrade" per aggiornare il pacchetto
all'ultima versione:

   (tutorial-env) $ python -m pip install --upgrade requests
   Collecting requests
   Installing collected packages: requests
     Found existing installation: requests 2.6.0
       Uninstalling requests-2.6.0:
         Successfully uninstalled requests-2.6.0
   Successfully installed requests-2.7.0

"python -m pip uninstall" seguito da uno o più nomi di pacchetti
rimuoverà i pacchetti dall'ambiente virtuale.

"python -m pip show" mostrerà informazioni su un particolare
pacchetto:

   (tutorial-env) $ python -m pip show requests
   ---
   Metadata-Version: 2.0
   Name: requests
   Version: 2.7.0
   Summary: Python HTTP for Humans.
   Home-page: http://python-requests.org
   Author: Kenneth Reitz
   Author-email: me@kennethreitz.com
   License: Apache 2.0
   Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
   Requires:

"python -m pip list" mostrerà tutti i pacchetti installati
nell'ambiente virtuale:

   (tutorial-env) $ python -m pip list
   novas (3.1.1.3)
   numpy (1.9.2)
   pip (7.0.3)
   requests (2.7.0)
   setuptools (16.0)

"python -m pip freeze" produrrà una lista simile dei pacchetti
installati, ma l'output utilizza il formato che "python -m pip
install" si aspetta. Una convenzione comune è mettere questa lista in
un file "requirements.txt":

   (tutorial-env) $ python -m pip freeze > requirements.txt
   (tutorial-env) $ cat requirements.txt
   novas==3.1.1.3
   numpy==1.9.2
   requests==2.7.0

Il "requirements.txt" può poi essere committato nel controllo di
versione e distribuito come parte di un'applicazione. Gli utenti
possono poi installare tutti i pacchetti necessari con "install -r":

   (tutorial-env) $ python -m pip install -r requirements.txt
   Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
     ...
   Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
     ...
   Collecting requests==2.7.0 (from -r requirements.txt (line 3))
     ...
   Installing collected packages: novas, numpy, requests
     Running setup.py install for novas
   Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

"pip" ha molte altre opzioni. Consulta la guida Installing Python
Modules per la documentazione completa su "pip". Quando hai scritto un
pacchetto e vuoi renderlo disponibile su Python Package Index,
consulta la guida dell'utente al packaging di Python.
