Programe melhor com Python – Use Virtual Environments

 

Normalmente essa semana eu disponibilizaria mais um post sobre Linux-PAM, porém devido a alguns contratempos, decidi segurar um pouco mais antes de voltar nesse assunto. Essa semana decidi comentar sobre uma funcionalidade que vejo poucos usarem, e que é extremamente útil quando você possui múltiplos projetos para trabalhar ao mesmo tempo. Essa semana o post irá tratar sobre o virtualenv: uma maneira de você isolar seu projeto e diminuir sua preocupação com pacotes quebrando sem nenhum motivo aparente.

 

O Problema

 

Atualmente, quando se trabalha com projetos de Python, é bem comum você chegar em situações que precisa baixar uma biblioteca externa do core da linguagem, como o SQLAlchemy, mongoengine, paramiko, entre outros. Existem situações em que ao baixar uma dessas bibliotecas, ela solicita que precisa atualizar outra para a versão mais recente, pois a mais recente é sua dependência. Agora imagina que seu ambiente de desenvolvimento, seu notebook, possui múltiplos projetos ao mesmo tempo sendo desenvolvidos, e por algum azar você atualizou um pacote que era usado por um desses projetos, e esse projeto não estava preparado para receber a nova versão da biblioteca. Seria um caos né? Imagina o tempo que você iria levar até descobrir que o problema é por causa de uma versão de biblioteca que removeu ou alterou alguma função vital para seu programa?

Falo isso por experiência própria: perdi horas debugando um projeto que eu estava envolvido para então descobrir que o Flask-SQLAlchemy havia removido parte de seu código que era mantido por compatibilidade das aplicações antigas. Após corrigir o programa para suportar a nova versão, o desenvolvimento seguiu fluido.

E teve até situações aonde eu desenvolvia um projeto em Python 2.7 e meu binário default de Python é o Python 3.6, e eu não posso alterar isso pois minha distribuição usa o 3.6 para seus programas e scripts. Alterar o link simbólico ou algo permanente seria inviável, apesar de colocar um PYTHON=”/usr/bin/python2.7″ no .bashrc já ajudar bastante.

 

Configurando virtualenv

 

O python possui uma solução para esse impasse: virtualenv. Um virtualenv nada mais é do que um diretório que contém a versão do Python e das bibliotecas que seu projeto utilizará, e isso será carregado ao você executar um arquivo bashrc no seu terminal. Dessa forma seu ambiente de desenvolvimento estará isolado dos demais, contanto que cada um possua seu próprio virtualenv. Para utilizar, primeiramente precisamos instalar o pacote virtualenv através do gerenciador de pacotes pip.

# pip install virtualenv
Collecting virtualenv
Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB)
100% |████████████████████████████████| 1.8MB 643kB/s 
Installing collected packages: virtualenv
Successfully installed virtualenv-15.1.0

Com o pacote instalado, execute o comando virtualenv –version para validar se a instalação ocorreu com sucesso:

# virtualenv --version
15.1.0

Antes de criarmos nosso ambiente de desenvolvimento, primeiramente iremos escrever um script simples de Python que utilize uma biblioteca que não esteja presente no core, ou em algum pacote pré instalado. O script abaixo utilizará a biblioteca wget para baixar o Kernel do Linux para sua máquina, porém essa biblioteca só pode ser baixada através do pip – não faz parte do core do python.

#!/usr/bin/python
from wget import download

download("https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.10.11.tar.xz")

Salve esse script como “virtteste.py” em qualquer diretório. Agora iremos criar nosso virtualenv pra testar e desenvolver esse projeto para algo a mais. Para criar seu virtualenv, primeiramente crie um diretório aonde deseja salvar todos eles, e então execute o comando abaixo:

$ virtualenv -p /usr/bin/python2.7 projeto

O parâmetro -p server para você informar qual o compilador default do seu projeto, e por ultimo informar o nome do seu projeto ( no caso chamamos de projeto mesmo). Isso levará alguns minutos para concluir, pois o virtualenv precisa preparar esse ambiente com uma instalação de Python e de todos os pacotes necessários para utilizar ele (como o pip e o setuptools). Para utilizar, basta carregar as variáveis de ambiente dentro de <projeto>/bin/activate que seu virtualenv estará carregado.

$ source projeto/bin/activate

Agora todos os pacotes que instalarmos enquanto estivermos com as variáveis de ambiente alteradas serão salvos dentro do diretório do virtualenv que você criou com o comando. Vamos prosseguir com o nosso projeto e baixar o pacote wget, e então validar se o nosso pequeno programa irá funcionar. Se nenhum erro for exibido, uma barra de progresso será exibida e, ao final, um arquivo chamado linux-4.10.11.tar.xz salvo no diretório que executou o script.

$ pip install wget
$ python virtteste.py
100% [........................................................................] 94250728 / 94250728

Por ultimo, caso não deseje mais utilizar esse virtualenv, basta executar o comando “deactivate” e você voltará a utilizar as variáveis default do bash. Poderá validar se realmente os pacotes do pip foram instaladas dentro do virtualenv executando o seu script novamente: agora ele deverá dar erro durante a execução.

$ deactivate
$ python virtteste.py 
Traceback (most recent call last):
 File "virtteste.py", line 2, in <module>
 from wget import download
ModuleNotFoundError: No module named 'wget'

 

Conclusões

 

Meu interesse no virtualenv foi levado a duas coisas, além dos motivos citados no começo desse post: limpeza, pois fica mais fácil de apagar um ambiente de dev e suas bibliotecas quando não preciso mais utilizar, e também por conta do Pycharm e os problemas de permissão para rodar um pip install. Eu poderia colocar meu usuário com a opção NOPASSWD no sudoers, mas achei que deveria ter uma maneira mais simples e mais elegante para fazer isso. Deixarei os links abaixo que utilizei para escrever esse post, caso desejam consultar.

  • http://python-guide-pt-br.readthedocs.io/en/latest/dev/virtualenvs/
  • https://virtualenv.pypa.io/en/stable/

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *