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.