12. Medii virtuale și pachete
*****************************


12.1. Introducere
=================

Aplicațiile Python folosesc adesea pachete și module care nu fac parte
din biblioteca standard. În diverse situații, o aplicație necesită o
versiune anumită a unei biblioteci, dat fiind că aplicația în cauză se
bazează pe faptul că o defecțiune de cod, din bibliotecă, a fost
corectată în versiunea respectivă sau, dimpotrivă, codul aplicației a
fost realizat cu elemente dintr-o versiune depășită a interfeței
bibliotecii în cauză.

De aceea, se poate întâmpla ca o singură instalare a sistemului Python
în calculatorul dumneavoastră să nu poată îndeplini în totalitate
cerințele tuturor aplicațiilor pe care intenționați să le folosiți.
Dacă, să zicem, aplicația A necesită versiunea 1.0 a modulului
*cutare* pe când aplicația B solicită prezența versiunii 2.0 a
respectivului modul, atunci cerințele intră în conflict una cu
cealaltă, deci, indiferent pe care dintre versiuni am instala-o, una
din aplicațiile A, B nu va putea funcționa.

Soluția unei asemenea probleme este să creăm un *mediu virtual*, adică
un *arbore* de directoare în care să se găsească o instalare (auto-
conținută) completă a sistemului Python corespunzând unei *versiuni*
precizate a Python-ului, instalare căreia să îi fie adăugate un număr
de pachete de interes particular.

Astfel, aplicații diferite vor putea fi rulate în medii virtuale
diferite. Ca o rezolvare a conflictului de cerințe din exemplul
anterior, aplicația A va putea dispune de propriul mediu virtual, în
care a fost instalată versiunea 1.0 a modulului respectiv, în timp ce
aplicația B va avea la dispoziție alt mediu virtual, cu versiunea 2.0
a aceluiași modul în funcțiune. Presupunând că, în urma unei
actualizări, aplicația B va avea nevoie de versiunea 3.0 a unei
biblioteci oarecare, instalarea ei nu va afecta în niciun fel mediul
aplicației A.


12.2. Crearea de medii virtuale
===============================

The module used to create and manage virtual environments is called
"venv".  "venv" will usually install the most recent version of Python
that you have available. If you have multiple versions of Python on
your system, you can select a specific Python version by running
"python3" or whichever version you want.

Pentru a crea un mediu virtual, decideți-vă asupra unui director în
care să îl plasați, apoi rulați modulul "venv" ca script, furnizându-i
calea de acces către directorul convenabil:

   python -m venv tutorial-env

Execuția comenzii (de către interpretor) va crea directorul
"tutorialul_de_python_un_mediu_virtual", dacă acesta nu există deja,
apoi va crea și restul (sub)directoarelor sale, în care se vor găsi o
copie a interpretorului de Python și varii fișiere ajutătoare.

O alegere frecventă în privința directorului unui mediu virtual este
dată de ".venv". Un atare nume va face ca directorul să le fie
*ascuns* comenzilor interpretorului de comenzi (de la englezescul, ca
jargon informatic, *shell*) activ în terminalul din care lucrați și,
din acest motiv, să nu le fie obstacol acestora, respectiv el nu va
avea nevoie de explicații despre motivul pentru care există (atunci
când, la câteva luni de la ultima sa folosire, veți fi uitat că face
parte din sistemul de directoare). În plus, alegerea acestui nume va
elimina potențialele conflicte cu fișierele ".env", care conțin
definițiile unor variabile de mediu, cerute de diverse unelte
informatice.

De îndată ce ați creat un mediu virtual, îl puteți *activa*.

În Windows, rulați:

   tutorial-env\Scripts\activate.bat

În Unix sau MacOS, rulați:

   source tutorial-env/bin/activate

(Acest script de activare a fost scris pentru interpretorul de comenzi
*bash*. Dacă îl folosiți ca interpretor fie pe **csh** fie pe
**fish**, atunci va trebui să utilizați scripturile corespunzătoare,
"activate.csh" ori "activate.fish".)

Activarea mediului virtual va schimba *promptul* interpretorului de
comenzi pe care îl întrebuințați în terminal pentru a vă informa ce
mediu virtual este în funcțiune, respectiv va modifica mediul pentru
ca rularea comenzii "python" să vă conducă chiar la versiunea
(special) instalată de Python cu care doriți să lucrați. De exemplu:

   $ 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']
   >>>


12.3. Administrarea pachetelor cu pip
=====================================

Putem instala, actualiza și elimina pachete cu ajutorul unui program
intitulat **pip**. În mod prestabilit, "pip" instalează pachete
preluate din Python Package Index (adică, *PyPI*; Catalogul pachetelor
Python). Pentru a putea răsfoi catalogul, este suficient să îi
vizitați pagina *web*.

"pip" are un număr de sub-comenzi (cu sintaxa *pip
nume_de_subcomandă*): "install", "uninstall", "freeze", șamd.
(Consultați ghidul Instalarea modulelor Python pentru o documentație
amănunțită referitoare la "pip".)

Puteți instala cea mai recentă versiune a unui pachet (precum *novas*)
specificându-i numele în comanda:

   (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

De asemeni, puteți instala o anumită versiune a unui pachet
(*requests*) introducându-i numele (în comandă), urmat de un "==" și
de numărul versiunii dorite:

   (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

If you re-run this command, "pip" will notice that the requested
version is already installed and do nothing.  You can supply a
different version number to get that version, or you can run "pip
install --upgrade" to upgrade the package to the latest version:

   (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

"pip uninstall" followed by one or more package names will remove the
packages from the virtual environment.

"pip show" will display information about a particular package:

   (tutorial-env) $ 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:

"pip list" will display all of the packages installed in the virtual
environment:

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

"pip freeze" will produce a similar list of the installed packages,
but the output uses the format that "pip install" expects. A common
convention is to put this list in a "requirements.txt" file:

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

În această situație, fișierul "cerințe.txt" va putea fi *comis* către
(baza de date a platformei de ) controlul versiunii, respectiv livrat
(către beneficiari) ca parte a aplicației construite de dumneavoastră.
Drept urmare, utilizatorii acesteia vor putea să își instaleze
pachetele de care are nevoie aplicația folosind "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" has many more options.  Consult the Installing Python Modules
guide for complete documentation for "pip".  When you've written a
package and want to make it available on the Python Package Index,
consult the Distributing Python Modules guide.
