Gerenciando suas dependências e ambientes python com pipenv

Já usei Node.js em alguns projetos e uma das coisas que mais gostei foi a forma que o Npm (Node Package Manager) e mais recentemente o Yarn criado pelo Facebook gerenciam as dependências do projeto. E de certa forma foi algo que sempre achei ‘fragmentado’ no ecossistema do python, a idéia do virtualenv para mim é perfeita, mas colocar a lista de dependências em arquivo requirements.txt feito a mão é um tanto que ridícula para mim. Por muito tempo busquei e até cogitei desenvolver algo que de certa forma ‘copiasse’ as idéias utilizadas no ecossistema do Node.js, mas a falta de tempo e de prioridade nisso nunca me fez passar da vontade. Porém, o Kenneth Reitz o criador do requests, essa blibioteca python que se você ainda não usou uma hora ou outra vai acabar usando, desenvolveu o Pipenv, uma ferramenta que de certa forma supre as necessidades que eu tinha e que com certeza vai te ajudar também.

Instalando o Pipenv

A idéia do Pipenv é basicamente juntar o virtualenv e o pip Pipfile em uma ferramenta única e através de um arquivo simples de configuração gerenciar todas as dependências e o ambiente do seu projeto, sejam elas dependências de produção ou desenvolvimento.

Antes mesmo de instalar o Pipenv, você deve se certificar de que tem o pip (python index package) instalado, para isso execute o comando:

$ pip -v

Caso ainda não o tenha instalado, faça o download desse script com o wget:

$ wget https://bootstrap.pypa.io/get-pip.py

e por fim execute-o com através do python:

$ sudo python get-pip.py

Verifique novamente se tudo deu certo:

$ pip -v

Com o pip devidamente instalado em sua máquina, para instalar o pipenv basta executar:

$ pip install pipenv

Criando seu primeiro ambiente

Com o Pipenv devidamente instalado, é hora de criarmos nosso primeiro ambiente. Mas o que seria um ambiente? Para você que vem de outras linguagens ou que simplesmente nunca ouviu falar em ambientes python, ambientes são uma forma de isolarmos uma versão do python e nossas dependências em pequenas ‘caixinhas de areia’ afim de evitarmos qualquer problema com a versão do python presente em nosso sistema ou dependências de outros projetos. E usando essa idéia, o pipenv automatiza a criação do nosso virtualenv e em conjunto gerência todas as dependências instaladas nele.

Para exemplificarmos de uma forma melhor sua utilização, criaremos um projeto django afim de tornar a coisa mais didática, para isso crie uma pasta chamada ‘myproject’ e dentro dela execute o comando abaixo:

$ pipenv --three

O comando acima vai criar nosso Pipfile que é o arquivo responsável pelo gerenciamento dos pacotes e uma pasta oculta .env que será responsável por armazenar nosso ambiente do python na versão 3 que foi criado graças a flag --three, caso quisessemos criar na versão 2, poderiamos usar a flag --two. Feito isso já podemos instalar o django em nosso ambiente, para isso execute:

$ pipenv install django

E tambem vamos instalar a django-extensions que é uma biblioteca que iremos utilizar somente em desenvolvimento. Pensando nisso o pipenv te da a possibilidade de fazer essa separação passando ao final do comando a flag --dev, ou seja, você pode indicar as bibliotecas que usará apenas em desenvolvimento, e no Pipfile ele faz essa separação, para isso execute:

$ pipenv install django-extensions --dev

Para darmos continuidade a partir daqui, primeiro precisaremos entender o funcionamento do Pipfile.

OBS: Lembre-se de adicionar a pasta .env em seu .gitignore sempre que trabalhar com essa ferramenta.

Entendendo o Pipfile

O Pipfile está para o python assim como o package.json está para o Node.js. Esse arquivo é o responsável por guardar todas as configurações e a lista de dependências do nosso projeto. Ele assume o papel do requirements.txt, arquivo esse que criavamos na mão, e gerenciavamos de forma totalmente manual.

O conteúdo do nosso Pipfile até o momento é esse:

Note que o Pipfile faz a separação entre dependências de desenvolvimento [dev-packages] e de produção [packages]. Além disso, ele informa a versão da nossa biblioteca, nesse caso, ele aceita a versão mais recente, mais se quisessemos indicar uma versão para as mesmas poderiamos fazer dessa forma:

Em resumo, tudo que você tem que saber é que quando for instalar alguma dependência, você tem que se atentar se utilizará a mesma apenas para desenvolvimento ou também em produção, caso a primeira alternativa seja sua realidade, utilize a flag --dev para salvar a mesma nas [dev-packages] do Pipfile.

Ativando nosso ambiente

Antes de tudo, você precisa saber que para se trabalhar dentro do nosso virtualenv você não precisa necessáriamente ativá-lo. O pipenv disponibiliza um comando para se trabalhar com o virtualenv mesmo que não o tenha ativado, para isso esamos o run, sua sintaxe é a seguinte:

$ pipenv run <command>

Se quisessemos listar as bibliotecas instaladas em nosso virtualenv antes mesmo de ativá-lo por exemplo:

$ pipenv run pip freeze

Teriamos uma saída parecida com essa:

appdirs==1.4.0
Django==1.10.5
packaging==16.8
pyparsing==2.1.10
six==1.10.0

Com as dependências devidamente instaladas e nosso ambiente criado, agora é hora de ativa-lo, para isso execute:

$ pipenv shell

Por padrão o ambiente é nomeado com o nome da pasta onde o mesmo foi criado. Se tudo deu certo, ao executar o comando abaixo, será retornado alguma versão do python 3:

(myproject)$ python --version

Verificando a integridade de ambiente

O pipenv também nos proporciona verificar a integridade do ambiente, ou seja, ele nos proporciona verificar se a nossa máquina atende aos requisitos necessário para execução do projeto como o tipo de plataforma, versão do python, etc.

O pipenv utiliza-se dos marcadores de ambiente do PEP 508 para realizar tais verificações. No seu arquivo Pipfile, adicione o seguinte bloco no final do arquivo:

Para verificar se a nossa máquina atende a esses requisitos, executamos o comando abaixo:

(myproject)$ pipenv check

Caso sua máquina atenda a esses requisitos, você receberá uma mensagem com algo parecido com isso:

Checking PEP 508 requirements...
Passed!

Caso contrário, configure os arquivos levando em consideração as configurações da sua máquina.

Criando o projeto

Com tudo instalado e o ambiente ativado, execute o comando abaixo para criar o projeto django:

(myproject)$ django-admin startproject myproject .

Se tudo deu certo, você terá a estrutura de arquivo abaixo:

├── manage.py
├── myproject
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── Pipfile
└── Pipfile.lock

Com o projeto devidamente criado, execute os migrates necessários para criação do banco:

(myproject)$ python manage.py migrate

E execute o servidor interno do django para executar o projeto em http://127.0.0.1:8000/

(myproject)$ python manage.py runserver

Comandos úteis

  • check - Checa se a sua máquina está de acordo com os marcadores de ambiente do PEP 508 setados no Pipfile, sintaxe:
(myproject)$ pipenv check
  • install - Instala uma dependência indicada, ou instala as dependências listadas no Pipfile caso alguma não seja indicada, sintaxe:
(myproject)$ pipenv install <package>

Para instalar todas as dependências presentes no Pipfile, execute:

(myproject)$ pipenv install

Para instalar todas as dependências de desenvolvimento presentes no Pipfile, execute:

(myproject)$ pipenv install --dev
  • lock - Cria um arquivo Pipfile.lock para o projeto caso não tenha criado, sintaxe:
(myproject)$ pipenv lock
  • run - Executa comandos dentro do virtualenv mesmo não o tendo ativado, sintaxe:
(myproject)$ pipenv run <command>
  • shell - Ativa o virtualenv, sintaxe:
(myproject)$ pipenv shell
  • uninstall - Desinsta-la uma dependência presente no virtualenv, sintaxe:
(myproject)$ pipenv uninstall <package>
  • update - Atualiza as dependências presentes no seu virtualenv, sintaxe:
(myproject)$ pipenv update

Conclusão

Como visto aqui, o pipenv é uma ótima alternativa à já conhecida casadinha virtualenv/pip, a ferramenta junta oque as duas ferramentas tem de melhor afim de viabilizar um workflow organizado e automatizado ao desenvolvedor.

❤ Gostou? Vamos espalhá-lo — curte e compartilha aí o/