funmachine


Deixe um comentário

Python + VirtualEnv

Tenho trabalhado ultimamente com a framework web Django e um dos maiores problemas com que tenho lidado ocorre quando por algum motivo preciso correr a framework noutro ambiente, por exemplo noutro PC. Ao contrário do desenvolvimento PHP, onde tipicamente temos uma stack estanque com todos os módulos PHP necessários, em Python e particularmente em Django, as coisas são um pouco diferentes. A verdade é que à medida que vamos desenvolvendo vamos também instalando uma série de módulos e dependências que depois precisamos de replicar se quisermos correr o ambiente de desenvolvimento sem problema. Mas nesse processo vários inconvenientes podem acontecer, caso a versão do Python usada originalmente para o projeto seja diferente da que temos instalada na máquina de destino, ou se alguns módulos tiverem também versões diferentes. Poderíamos simplesmente atualizar a versão do Python e dos módulos necessários para a que o nosso projeto utiliza, mas aí os outros projetos podem deixar de funcionar! Se, pelo contrário, deixarmos as versões que temos no sistema, então aí pode o projeto que queremos migrar não correr!

Claro que já muita gente se deparou com uma situação destas, e a solução para gerir este inferno de versões e dependências é utilizar Virtual Environments. A ideia é muito simples: utilizamos um software que cria virtual envs na nosso máquina é nos permite alternar entre eles. Enquanto estivermos com um virtual env activado, todos os módulos Python instalados ficam associados a esse virtual env. Simples!

Vamos então aprender mais um pouco sobre um dos softwares que podemos utilizar para criar Virtual Environments em Python, chamado (naturalmente) VirtualEnv.

Para instalar o VirtualEnv podem usar a ferramenta easy_install:

$ easy_install virtualenv

Depois de instalado com sucesso, podem criar um ambiente virtual com o seguinte comando:

$ virtualenv my_venv

Com este comando é criado um ambiente virtual já com as packages base Python, ou seja, todas as global site-packages Python que tinham instalado anteriormente são herdadas, incluindo o próprio Python!

Caso queiram criar um VirtualEnv “vazio” usem o comando:

$ virtualenv  –no-site-packages my_venv

Isto pode ser útil para, por exemplo, criar um VirtualEnv com uma versão diferente Python da global.

Depois de criado o VirtualEnv, podemos ativá-lo usando o comando:

$ source my-venv/bin/activate

Desta forma, estamos a trabalhar neste VirtualEnv. Qualquer tarefa Python que usem vai usar este VirtualEnv. Notem como aparece o nome do VirtualEnv na consola.

Agora queremos instalar uma package Python neste VirtualEnv. Para isso, com o VirtualEnv activado, simplesmente usamos o easy_install (ou outra ferramenta de instalação de packages Python):

$(my_venv) easy_install yolk

A assim o yolk é instalado no VirtualEnv “my_venv”.

Quando quisermos sair de um VirtualEnv, simplesmente usamos o comando:

$(my_venv) deactivate

Simples, não? Uma pequena nota: o yolk, entre outras coisas, serve para sabermos quais os packages Python que temos instalados. Se correrem o comando:

$(my_venv) yolk -l

são listadas todas as packages e suas versões que atualmente estão instaladas no ambiente virtual ativo, neste caso “my_venv”. Se nenhum ambiente virtual estiver ativo então são listadas as packages globais.

Ok, temos o nosso trabalho simplificado, podemos criar VirtualEnv facilmente, e se depois quisermos correr um projeto noutro ambiente de desenvolvimento, basta recriar o VirtualEnv. Além disso, há outra tarefa que fica simplificada – testar novas versões de packages! Basta criar um virtualenv novo e instalar as novas versões e verificar como o nosso programa funciona com as novas versões. A qualquer momento podemos voltar ao ambiente estável, bastando trocar de VirtualEnv.

Mas este processo de gerir as dependências do nosso projeto ainda não é perfeito! Recriar VirtualEnvs dá trabalho, temos que saber quais as packages instaladas e voltar a instalar tudo de novo! O yolk facilita o trabalho, mas ainda assim acho que precisa ser mais automático! A solução é simples também: vamos criar um script Python que trata de instalar por nós as dependências!

Criem um ficheiro Python com este código:

import virtualenv, textwrap
output = virtualenv.create_bootstrap_script(textwrap.dedent("""
def after_install(options, home_dir):
    subprocess.call([join(home_dir, 'bin', 'easy_install'),
                    'yolk'])
"""))
print output

Gravem o ficheiro, por exemplo, como main.py

No terminal, corram:

$ python main.py > install-venv.py

E depois corram o ficheiro Python resultante com o nome do VirtualEnv que querem recriar como parâmetro:

$ python install-venv.py my_venv

Et voilá! Este script trata de criar o VirtualEnv my_venv, com todas packages que quisermos instalar! (neste exemplo apenas yolk)