12. Ambientes virtuais e pacotes
********************************


12.1. Introdução
================

Aplicações em Python normalmente usam pacotes e módulos que não vêm
como parte da instalação padrão. Aplicações as vezes necessitam uma
versão específica de uma biblioteca, porque ela requer que algum
problema em particular tenha sido consertado ou foi escrita
utilizando-se de uma versão obsoleta da interface da biblioteca.

Isso significa que talvez não seja possível que uma instalação Python
preencha os requisitos de qualquer aplicação. Se uma aplicação A
necessita a versão 1.0 de um módulo particular mas a aplicação B
necessita a versão 2.0, os requisitos entrarão em conflito e instalar
qualquer uma das duas versões 1.0 ou 2.0 fará com que uma das
aplicações não consiga executar.

A solução para este problema é criar um *ambiente virtual*, uma árvore
de diretórios que contém uma instalação Python para uma versão
particular do Python, além de uma série de pacotes adicionais.

Diferentes aplicações podem então usar diferentes ambientes virtuais.
Para resolver o exemplo anterior de requisitos conflitantes, a
aplicação A deve ter seu próprio ambiente virtual com a versão 1.0
instalada enquanto a aplicação B vai possuir outro ambiente virtual
com a versão 2.0. Se a aplicação B precisar fazer uma atualização para
a versão 3.0, isso não afetará o ambiente da aplicação A.


12.2. Criando ambientes virtuais
================================

O módulo usado para criar e gerenciar ambientes virtuais é chamado
"venv". O "venv" normalmente irá instalar a versão mais recente de
Python que você tiver disponível. Se você tiver múltiplas versões de
Python no seu sistema, você pode selecionar uma versão específica do
Python executando "python3" ou qualquer versão que você desejar.

Para criar um ambiente virtual, escolha um diretório onde deseja
colocá-lo e execute o módulo "venv" como um script com o caminho do
diretório:

   python3 -m venv tutorial-env

Isso irá criar o diretório "tutorial-env" se ele não existir e também
criará diretórios dentro dele contendo uma cópia do interpretador
Python, a biblioteca padrão e diversos arquivos de suporte.

Uma vez criado seu ambiente virtual, você deve ativá-lo.

No Windows, execute:

   tutorial-env\Scripts\activate.bat

No Unix ou no MacOS, executa:

   source tutorial-env/bin/activate

(Este script é escrito para o shell bash. Se você usa shells **csh**
ou **fish**, existem scripts alternativos "activate.csh" e
"activate.fish" para utilização.)

Ao ativar seu ambiente virtual haverá uma mudança no prompt do shell
para mostrar qual ambiente virtual você está usando e modificará o
ambiente para que quando você executar "python" ativar a versão e
instalação do Python particular àquele ambiente. Por exemplo:

   $ 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. Gerenciando pacotes com o pip
===================================

Você pode instalar, atualizar e remover pacotes usando um programa
chamado **pip**. Por padrão "pip" irá instalar pacotes do Python
Package Index, <https://pypi.org>. Você pode navegar pelo Python
Package Index através do seu navegador web, ou usando os recursos
limitados de busca do "pip":

   (tutorial-env) $ pip search astronomy
   skyfield               - Elegant astronomy for Python
   gary                   - Galactic astronomy and gravitational dynamics.
   novas                  - The United States Naval Observatory NOVAS astronomy library
   astroobs               - Provides astronomy ephemeris to plan telescope observations
   PyAstronomy            - A collection of astronomy related tools for Python.
   ...

"pip" tem uma série de subcomandos: "search", "install", "uninstall",
"freeze", etc. (Consulte o guia Instalando Módulos Python para a
documentação completa do "pip".)

Você pode instalar a última versão de um pacote apenas especificando
nome do pacote:

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

Você também pode instalar uma versão específica de um pacote dando o
nome do pacote seguido por "==" e o número da versão:

   (tutorial-env) $ 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 você re-executar esse comando, "pip" vai perceber que aquela versão
requisitada já foi instalada e não fará nada. Você pode definir uma
versão diferente para instalar aquela versão ou você pode executar
"pip install --upgrade"  para fazer a atualização do pacote para a
última versão.

   (tutorial-env) $ 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" seguido do nome de um ou mais pacotes irá remover os
pacotes do ambiente virtual.

"pip show" irá mostrar informações sobre um pacote em particular:

   (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" irá apresentar uma lista de todos os pacotes instalados no
ambiente virtual.

   (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" irá mostrar uma lista dos pacotes instalados, mas o
resultado usa o formato que o "pip install" aceita. Uma convenção
comum é colocar essa lista em um arquivo chamado "requirements.txt":

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

O arquivo "requirements.txt" pode ser submetido no controle de versão
e adicionado como parte da aplicação. Usuários poderão então instalar
todos os pacotes necessários com um "install -r":

   (tutorial-env) $ 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" tem inúmeras outras opções. Consulte o guia Instalando Módulos
Python para a documentação completa do "pip". Quando você escrever um
pacote e desejar deixá-lo disponível no Python Package Index, consulte
o guia Distribuindo Módulos Python.
