Entendendo o pip — O instalador de pacotes do Python
Bibliotecas são componentes essenciais na programação, pois permitem que desenvolvedores reutilizem código já escrito, economizando tempo e esforço. Elas fornecem abstrações de alto nível, promovendo um desenvolvimento mais rápido e protegendo os usuários de detalhes complexos de implementação — o que permite que os desenvolvedores foquem na lógica principal da aplicação.
Para facilitar a distribuição e o compartilhamento dessas bibliotecas, temos repositórios online como o GitHub (para código-fonte em geral), o npm (para bibliotecas JavaScript) e o PyPI (para pacotes Python). No PyPI podemos encontrar bibliotecas como requests (para lidar com chamadas HTTP), pandas (para análise de dados), pyspark (para processamento de dados em larga escala) e muitas outras.
Com bibliotecas, não precisamos reinventar a roda — e elas são distribuídas gratuitamente pela internet! Mas surge a pergunta: como podemos usar essas bibliotecas?
Usando bibliotecas Python
Quando estamos começando na programação, é comum pensar que usar uma biblioteca é algo bem direto: basta copiar o código-fonte para a sua pasta e começar a usar no seu código.
Isso não está errado, mas seria uma tarefa cansativa ter que procurar no PyPI a biblioteca desejada, baixar o código-fonte, identificar as pastas necessárias e colá-las no diretório do seu projeto…
Lembre-se de que isso teria que ser feito várias vezes no mesmo projeto, já que normalmente trabalhamos com várias dependências.
Além disso, você teria que atualizar manualmente o código de cada biblioteca toda vez que o mantenedor publicasse uma nova versão no PyPI para corrigir bugs ou adicionar recursos.
Não é só copiar e colar
Copiar e colar código-fonte no seu workspace traria outros problemas além do esforço manual.
Um deles é que estaríamos duplicando código de forma desorganizada, pois a mesma biblioteca seria copiada e espalhada em vários projetos diferentes pela internet.
Outro problema é o gerenciamento de dependências.
Imagine o seguinte cenário: você quer criar uma nova biblioteca, mas quer usar recursos de outras bibliotecas (dependências) disponíveis no PyPI.
Agora, alguém vai usar a sua biblioteca — e essa pessoa também usa outra biblioteca que é exatamente a mesma que está nas suas dependências, mas em uma versão mais recente.
Se fosse tudo apenas “copiar e colar”, como esse desenvolvedor lidaria com essa situação?
Mesmo que ambas as versões fossem copiadas (uma para sua dependência e outra para o projeto dele), como o Python saberia qual delas deve ser usada no import?
É aqui que entra o pip, o instalador de pacotes do Python.
Instalador de pacotes do Python
Agora você já entende por que precisamos de um gerenciador de pacotes.
No caso do Python, temos o pip — uma ferramenta de linha de comando para instalar pacotes Python — que é o gerenciador de pacotes “oficial” da linguagem (embora existam alternativas).
Ele simplifica o processo de baixar e instalar pacotes do PyPI e de outros repositórios — no fim das contas, é como um “copiar e colar” automatizado e inteligente.
Bibliotecas instaladas com o pip (ou outros gerenciadores de pacotes) ficam disponíveis para serem importadas em seus módulos e subpacotes.
Veja algumas das suas principais funcionalidades:
- Instalação fácil de pacotes: instale bibliotecas Python com a CLI do
pip - Resolução de dependências: resolve e instala automaticamente as dependências necessárias de um pacote, garantindo um processo de instalação fluido.
- Desinstalação de pacotes: com o
pip, você pode remover pacotes e suas dependências associadas de forma limpa, evitando bagunça no ambiente. - Gerenciamento de versões: o
pippermite instalar versões específicas ou as mais recentes de cada pacote.
Como usar o pip
Normalmente, o pip já vem instalado junto com o Python.
Porém, se por algum motivo você não o tiver, é possível obtê-lo baixando o script get-pip.py e executando-o com o interpretador Python (veja aqui as instruções completas de instalação).
Agora, vamos ver como realizar algumas operações comuns de gerenciamento de pacotes usando o pip.
Instalando pacotes
Use o comando pip install seguido do nome do pacote para instalar uma biblioteca.
# instala o pacote pandas do PyPI
pip install pandas
# instala múltiplos pacotes de uma vez — pytest, sphinx e mypy
pip install pytest sphinx mypy
# instala um pacote com opcionais
pip install "fastapi[all]"
# instala uma versão específica do pacote requests
pip install requests==2.26.0
# instala a partir de um repositório do GitHub (desde que o pacote seja instalável)
pip install 'git+https://github.com/pydantic/pydantic'
Atualizando pacotes
Para atualizar um pacote já instalado para a versão mais recente, use:
pip install --upgrade requests
Quando atualizamos um pacote, a versão antiga é removida e substituída pela nova. Não é possível ter múltiplas versões da mesma biblioteca instaladas no mesmo ambiente.
Desinstalando pacotes
Remova um pacote e suas dependências com:
pip uninstall pandas
Listando seus pacotes
Com o comando pip list, você pode listar todos os pacotes instalados no seu ambiente:
pip list
É interessante notar que provavelmente você terá uma lista grande de pacotes, mesmo que tenha instalado apenas uma única biblioteca, pois o pip também instala todas as dependências necessárias para que tudo funcione corretamente.
Assim é a aparência de um ambiente novo ao rodar pip list:
Package Version
------------ -------
pip 22.0.2
setuptools 59.6.0
E assim ele fica depois de instalar apenas um pacote (pytest):
Package Version
-------------- -------
exceptiongroup 1.1.2
iniconfig 2.0.0
packaging 23.1
pip 22.0.2
pluggy 1.2.0
pytest 7.4.0
setuptools 59.6.0
tomli 2.0.1
O pacote pytest, por exemplo, traz consigo 5 novas dependências.
Gerenciando dependências com requirements.txt
Quando você instala bibliotecas usando o pip, o código delas é colocado ao lado do interpretador Python no sistema de arquivos.
Assim, conseguimos manter as dependências separadas do nosso código-fonte.
Mas, se compartilharmos o código com colegas, eles terão erros de ImportError, certo?
E como evitar conflitos entre versões diferentes da mesma biblioteca em projetos distintos?
Para lidar com esses problemas, usamos arquivos de requisitos e ambientes virtuais.
Se quiser se aprofundar nesse assunto, escrevi um artigo completo sobre Ambientes Virtuais Python aqui.
Em resumo, os ambientes virtuais nos ajudam a isolar as dependências por projeto. Assim, cada projeto pode ter seu próprio conjunto de bibliotecas e versões específicas.
Dentro do ambiente virtual, podemos instalar as dependências e usar arquivos de requirements para facilitar a instalação de tudo o que for necessário. Esses arquivos são textos simples que listam as dependências do projeto, suas versões e fontes. Podemos gerar um arquivo de requisitos com o comando:
pip freeze > requirements.txt
Depois, sempre que precisarmos compartilhar o projeto ou configurá-lo novamente, podemos instalar todas as dependências com:
pip install -r requirements.txt
Os arquivos de requirements devem ser incluídos no seu repositório Git, caso o projeto esteja sendo versionado.
Por outro lado, o seu ambiente virtual não deve ser enviado ao repositório remoto — portanto, certifique-se de adicioná-lo ao seu arquivo .gitignore.
Conclusão
Compreender os fundamentos do gerenciamento de pacotes é essencial para qualquer desenvolvedor, já que é um componente básico em praticamente todos os ecossistemas de linguagens de programação. Desde a instalação de bibliotecas simples até o gerenciamento de dependências complexas, um gerenciador de pacotes simplifica o processo e garante uma experiência de desenvolvimento fluida.