Um conjunto de ferramentas de linha de comando para ajudá-lo a manter seus pacotes baseados em pip
atualizados, mesmo quando você os fixa. Você os fixa, certo? (Ao construir seu aplicativo Python e suas dependências para produção, você quer ter certeza de que suas construções são previsíveis e determinísticas.)
Semelhante ao pip
, pip-tools
deve ser instalado em cada um dos ambientes virtuais do seu projeto:
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
Nota : todos os comandos de exemplo restantes assumem que você ativou o ambiente virtual do seu projeto.
pip-compile
O comando pip-compile
permite compilar um arquivo requirements.txt
a partir de suas dependências, especificadas em pyproject.toml
, setup.cfg
, setup.py
ou requirements.in
.
Execute-o com pip-compile
ou python -m piptools compile
(ou pipx run --spec pip-tools pip-compile
se pipx
foi instalado com a versão apropriada do Python). Se você usar várias versões do Python, também poderá executar py -XY -m piptools compile
no Windows e pythonX.Y -m piptools compile
em outros sistemas.
pip-compile
deve ser executado no mesmo ambiente virtual do seu projeto para que as dependências condicionais que exigem uma versão específica do Python ou outros marcadores de ambiente sejam resolvidas em relação ao ambiente do seu projeto.
Nota : Se pip-compile
encontrar um arquivo requirements.txt
existente que atenda às dependências, nenhuma alteração será feita, mesmo que haja atualizações disponíveis. Para compilar do zero, primeiro exclua o arquivo requirements.txt
existente ou consulte Atualizando requisitos para abordagens alternativas.
pyproject.toml
O arquivo pyproject.toml
é o padrão mais recente para configuração de pacotes e aplicativos e é recomendado para novos projetos. pip-compile
suporta a instalação de project.dependencies
e também de project.optional-dependencies
. Graças ao fato de este ser um padrão oficial, você pode usar pip-compile
para fixar as dependências em projetos que usam ferramentas de empacotamento modernas que aderem aos padrões, como Setuptools, Hatch ou flit.
Suponha que você tenha um aplicativo Python 'foobar' empacotado usando Setuptools
e queira fixá-lo para produção. Você pode declarar os metadados do projeto como:
[ build-system ]
requires = [ " setuptools " , " setuptools-scm " ]
build-backend = " setuptools.build_meta "
[ project ]
requires-python = " >=3.9 "
name = " foobar "
dynamic = [ " dependencies " , " optional-dependencies " ]
[ tool . setuptools . dynamic ]
dependencies = { file = [ " requirements.in " ] }
optional-dependencies.test = { file = [ " requirements-test.txt " ] }
Se você possui um aplicativo Django empacotado usando Hatch
e deseja fixá-lo para produção. Você também deseja fixar suas ferramentas de desenvolvimento em um arquivo PIN separado. Você declara django
como uma dependência e cria uma dependência opcional dev
que inclui pytest
:
[ build-system ]
requires = [ " hatchling " ]
build-backend = " hatchling.build "
[ project ]
name = " my-cool-django-app "
version = " 42 "
dependencies = [ " django " ]
[ project . optional-dependencies ]
dev = [ " pytest " ]
Você pode produzir seus arquivos PIN tão facilmente quanto:
$ pip-compile -o requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --output-file=requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
django==4.1.7
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
$ pip-compile --extra dev -o dev-requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
#
asgiref==3.6.0
# via django
attrs==22.2.0
# via pytest
django==4.1.7
# via my-cool-django-app (pyproject.toml)
exceptiongroup==1.1.1
# via pytest
iniconfig==2.0.0
# via pytest
packaging==23.0
# via pytest
pluggy==1.0.0
# via pytest
pytest==7.2.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
# via django
tomli==2.0.1
# via pytest
Isso é ótimo para fixar seus aplicativos, mas também para manter estável o CI do seu pacote Python de código aberto.
setup.py
e setup.cfg
pip-compile
também tem suporte completo para projetos baseados em setup.py
- e setup.cfg
que usam setuptools
.
Basta definir suas dependências e extras normalmente e executar pip-compile
como acima.
requirements.in
Você também pode usar arquivos de texto simples para suas necessidades (por exemplo, se não quiser que seu aplicativo seja um pacote). Para usar um arquivo requirements.in
para declarar a dependência do Django:
# requirements.in
django
Agora, execute pip-compile requirements.in
:
$ pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile requirements.in
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
E produzirá seu requirements.txt
, com todas as dependências do Django (e todas as dependências subjacentes) fixadas.
(requisitos de atualização)=
pip-compile
gera um arquivo requirements.txt
usando as versões mais recentes que atendem às dependências especificadas nos arquivos suportados.
Se pip-compile
encontrar um arquivo requirements.txt
existente que atenda às dependências, nenhuma alteração será feita, mesmo que haja atualizações disponíveis.
Para forçar pip-compile
a atualizar todos os pacotes em um requirements.txt
existente, execute pip-compile --upgrade
.
Para atualizar um pacote específico para a versão mais recente ou específica, use o sinalizador --upgrade-package
ou -P
:
# only update the django package
$ pip-compile --upgrade-package django
# update both the django and requests packages
$ pip-compile --upgrade-package django --upgrade-package requests
# update the django package to the latest, and requests to v2.0.0
$ pip-compile --upgrade-package django --upgrade-package requests==2.0.0
Você pode combinar --upgrade
e --upgrade-package
em um comando, para fornecer restrições nas atualizações permitidas. Por exemplo, para atualizar todos os pacotes enquanto restringe as solicitações para a versão mais recente inferior a 3.0:
$ pip-compile --upgrade --upgrade-package ' requests<3.0 '
Se você quiser usar o modo de verificação de hash disponível no pip
desde a versão 8.0, pip-compile
oferece o sinalizador --generate-hashes
:
$ pip-compile --generate-hashes requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --generate-hashes requirements.in
#
asgiref==3.6.0
--hash=sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac
--hash=sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506
# via django
django==4.1.7
--hash=sha256:44f714b81c5f190d9d2ddad01a532fe502fa01c4cb8faf1d081f4264ed15dcd8
--hash=sha256:f2f431e75adc40039ace496ad3b9f17227022e8b11566f4b363da44c7e44761e
# via -r requirements.in
sqlparse==0.4.3
--hash=sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34
--hash=sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268
# via django
Para gerar os requisitos fixados em um nome de arquivo diferente de requirements.txt
, use --output-file
. Isto pode ser útil para compilar vários arquivos, por exemplo, com restrições diferentes no Django para testar uma biblioteca com ambas as versões usando tox:
$ pip-compile --upgrade-package ' django<1.0 ' --output-file requirements-django0x.txt
$ pip-compile --upgrade-package ' django<2.0 ' --output-file requirements-django1x.txt
Ou para gerar a saída padrão, use --output-file=-
:
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
pip
Quaisquer sinalizadores ou argumentos pip
válidos podem ser transmitidos com a opção --pip-args
do pip-compile
, por exemplo
$ pip-compile requirements.in --pip-args " --retries 10 --timeout 30 "
Você pode definir padrões de nível de projeto para pip-compile
e pip-sync
gravando-os em um arquivo de configuração no mesmo diretório dos arquivos de entrada de requisitos (ou no diretório de trabalho atual se estiver canalizando a entrada de stdin). Por padrão, pip-compile
e pip-sync
procurarão primeiro um arquivo .pip-tools.toml
e depois em seu pyproject.toml
. Você também pode especificar um arquivo de configuração TOML alternativo com a opção --config
.
É possível especificar valores de configuração globalmente e específicos do comando. Por exemplo, para gerar hashes pip
por padrão na saída do arquivo de requisitos resultante, você pode especificar em um arquivo de configuração:
[ tool . pip-tools ]
generate-hashes = true
As opções para pip-compile
e pip-sync
que podem ser usadas mais de uma vez devem ser definidas como listas em um arquivo de configuração, mesmo que tenham apenas um valor.
pip-tools
suporta valores padrão para todos os sinalizadores de linha de comando válidos de seus subcomandos. As chaves de configuração podem conter sublinhados em vez de travessões, portanto o acima também pode ser especificado neste formato:
[ tool . pip-tools ]
generate_hashes = true
Os padrões de configuração específicos para pip-compile
e pip-sync
podem ser colocados em seções separadas. Por exemplo, para executar, por padrão, uma simulação com pip-compile
:
[ tool . pip-tools . compile ] # "sync" for pip-sync
dry-run = true
Isso não afeta o comando pip-sync
, que também possui uma opção --dry-run
. Observe que as configurações locais têm preferência sobre as globais de mesmo nome, sempre que ambas são declaradas, portanto, isso também faria com que pip-compile
gerasse hashes, mas descartasse a configuração global de simulação:
[ tool . pip-tools ]
generate-hashes = true
dry-run = true
[ tool . pip-tools . compile ]
dry-run = false
Você pode estar agrupando o comando pip-compile
em outro script. Para evitar confundir os consumidores de seu script customizado, você pode substituir o comando de atualização gerado na parte superior dos arquivos de requisitos configurando a variável de ambiente CUSTOM_COMPILE_COMMAND
.
$ CUSTOM_COMPILE_COMMAND= " ./pipcompilewrapper " pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# ./pipcompilewrapper
#
asgiref==3.6.0
# via django
django==4.1.7
# via -r requirements.in
sqlparse==0.4.3
# via django
Se você tiver ambientes diferentes para os quais precisa instalar pacotes diferentes, mas compatíveis, poderá criar arquivos de requisitos em camadas e usar uma camada para restringir a outra.
Por exemplo, se você tem um projeto Django onde deseja a versão 2.1
mais recente em produção e durante o desenvolvimento deseja usar a barra de ferramentas de depuração do Django, então você pode criar dois arquivos *.in
, um para cada camada:
# requirements.in
django<2.2
No topo dos requisitos de desenvolvimento dev-requirements.in
você usa -c requirements.txt
para restringir os requisitos de desenvolvimento a pacotes já selecionados para produção em requirements.txt
.
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
Primeiro, compile requirements.txt
normalmente:
$ pip-compile
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile
#
django==2.1.15
# via -r requirements.in
pytz==2023.3
# via django
Agora compile os requisitos de desenvolvimento e o arquivo requirements.txt
será usado como restrição:
$ pip-compile dev-requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile dev-requirements.in
#
django==2.1.15
# via
# -c requirements.txt
# django-debug-toolbar
django-debug-toolbar==2.1
# via -r dev-requirements.in
pytz==2023.3
# via
# -c requirements.txt
# django
sqlparse==0.4.3
# via django-debug-toolbar
Como você pode ver acima, mesmo que uma versão 2.2
do Django esteja disponível, os requisitos de desenvolvimento incluem apenas uma versão 2.1
do Django porque eles eram restritos. Agora ambos os arquivos de requisitos compilados podem ser instalados com segurança no ambiente de desenvolvimento.
Para instalar requisitos na fase de produção, use:
$ pip-sync
Você pode instalar requisitos no estágio de desenvolvimento:
$ pip-sync requirements.txt dev-requirements.txt
Você pode usar pip-compile
como gancho para o pré-commit. Consulte a documentação pré-confirmação para obter instruções. Exemplo .pre-commit-config.yaml
:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
Você pode querer personalizar pip-compile
args configurando args
e/ou files
, por exemplo:
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
files : ^requirements/production.(in|txt)$
args : [--index-url=https://example.com, requirements/production.in]
Se você tiver vários arquivos de requisitos, crie um gancho para cada arquivo.
repos :
- repo : https://github.com/jazzband/pip-tools
rev : 7.4.1
hooks :
- id : pip-compile
name : pip-compile setup.py
files : ^(setup.py|requirements.txt)$
- id : pip-compile
name : pip-compile requirements-dev.in
args : [requirements-dev.in]
files : ^requirements-dev.(in|txt)$
- id : pip-compile
name : pip-compile requirements-lint.in
args : [requirements-lint.in]
files : ^requirements-lint.(in|txt)$
- id : pip-compile
name : pip-compile requirements.in
args : [requirements.in]
files : ^requirements.(in|txt)$
pip-sync
Agora que você tem um requirements.txt
, você pode usar pip-sync
para atualizar seu ambiente virtual para refletir exatamente o que está nele. Isso instalará/atualizará/desinstalará tudo o que for necessário para corresponder ao conteúdo requirements.txt
.
Execute-o com pip-sync
ou python -m piptools sync
. Se você usar várias versões do Python, também poderá executar py -XY -m piptools sync
no Windows e pythonX.Y -m piptools sync
em outros sistemas.
pip-sync
deve ser instalado e executado no mesmo ambiente virtual do seu projeto para identificar quais pacotes instalar ou atualizar.
Tenha cuidado : pip-sync
deve ser usado apenas com um requirements.txt
gerado por pip-compile
.
$ pip-sync
Uninstalling flake8-2.4.1:
Successfully uninstalled flake8-2.4.1
Collecting click==4.1
Downloading click-4.1-py2.py3-none-any.whl (62kB)
100% |................................| 65kB 1.8MB/s
Found existing installation: click 4.0
Uninstalling click-4.0:
Successfully uninstalled click-4.0
Successfully installed click-4.1
Para sincronizar várias listas de dependências *.txt
, basta passá-las por meio de argumentos de linha de comando, por exemplo
$ pip-sync dev-requirements.txt requirements.txt
Passar argumentos vazios faria com que o padrão fosse requirements.txt
.
Quaisquer sinalizadores ou argumentos válidos pip install
podem ser passados com a opção --pip-args
do pip-sync
, por exemplo
$ pip-sync requirements.txt --pip-args " --no-cache-dir --no-deps "
Nota : pip-sync
não atualizará ou desinstalará ferramentas de empacotamento como setuptools
, pip
ou o próprio pip-tools
. Use python -m pip install --upgrade
para atualizar esses pacotes.
requirements.in
e requirements.txt
para o controle de origem? Geralmente, sim. Se você deseja uma instalação de ambiente reproduzível disponível a partir de seu controle de origem, então sim, você deve confirmar requirements.in
e requirements.txt
para o controle de origem.
Observe que se você estiver implantando em vários ambientes Python (leia a seção abaixo), deverá enviar um arquivo de saída separado para cada ambiente Python. Sugerimos usar o formato {env}-requirements.txt
(ex: win32-py3.7-requirements.txt
, macos-py3.10-requirements.txt
, etc.).
requirements.in
e pip-compile
requirements.txt
diferentes ambientesAs dependências de um pacote podem mudar dependendo do ambiente Python no qual ele está instalado. Aqui, definimos um ambiente Python como a combinação de sistema operacional, versão Python (3.7, 3.8, etc.) e implementação Python (CPython, PyPy, etc.). Para uma definição exata, consulte as combinações possíveis de marcadores ambientais PEP 508.
Como o requirements.txt
resultante pode diferir para cada ambiente, os usuários devem executar pip-compile
em cada ambiente Python separadamente para gerar um requirements.txt
válido para cada ambiente. O mesmo requirements.in
pode ser usado como arquivo de origem para todos os ambientes, usando marcadores de ambiente PEP 508 conforme necessário, da mesma forma que seria feito para uso regular pip
em vários ambientes.
Se o requirements.txt
gerado permanecer exatamente o mesmo para todos os ambientes Python, ele poderá ser usado em ambientes Python com segurança. Mas os usuários devem ter cuidado, pois qualquer atualização de pacote pode introduzir dependências dependentes do ambiente, tornando qualquer requirements.txt
recém-gerado também dependente do ambiente. Como regra geral, é aconselhável que os usuários sempre executem pip-compile
em cada ambiente Python de destino para evitar problemas.
pip-tools
é uma ótima ferramenta para melhorar a reprodutibilidade de compilações. Mas há algumas coisas que você deve ter em mente.
pip-compile
produzirá resultados diferentes em ambientes diferentes, conforme descrito na seção anterior.pip
deve ser usado com a variável de ambiente PIP_CONSTRAINT
para bloquear dependências em ambientes de construção conforme documentado em #8439. Continuando o exemplo pyproject.toml
anterior, a criação de um único arquivo de bloqueio poderia ser feita da seguinte forma:
$ pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
asgiref==3.5.2
# via django
attrs==22.1.0
# via pytest
backports-zoneinfo==0.2.1
# via django
django==4.1
# via my-cool-django-app (pyproject.toml)
editables==0.3
# via hatchling
hatchling==1.11.1
# via my-cool-django-app (pyproject.toml::build-system.requires)
iniconfig==1.1.1
# via pytest
packaging==21.3
# via
# hatchling
# pytest
pathspec==0.10.2
# via hatchling
pluggy==1.0.0
# via
# hatchling
# pytest
py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
# via django
tomli==2.0.1
# via
# hatchling
# pytest
Alguns back-ends de construção também podem solicitar dependências de construção dinamicamente usando os ganchos get_requires_for_build_
descritos em PEP 517 e PEP 660. Isso será indicado na saída com um dos seguintes sufixos:
(pyproject.toml::build-system.backend::editable)
(pyproject.toml::build-system.backend::sdist)
(pyproject.toml::build-system.backend::wheel)
pip-compile-multi - wrapper de comando pip-compile para vários arquivos de requisitos de referência cruzada.
pipdeptree para imprimir a árvore de dependências dos pacotes instalados.
Destaque de sintaxe requirements.txt
requirements.in
Esta seção lista os recursos pip-tools
que estão atualmente obsoletos.
--allow-unsafe
será habilitado por padrão (#989). Use --no-allow-unsafe
para manter o comportamento antigo. Recomenda-se passar --allow-unsafe
agora para se adaptar às próximas mudanças.--resolver=backtracking
.--strip-extras
será habilitado por padrão (#1613). Use --no-strip-extras
para manter o comportamento antigo.Você pode escolher entre o resolvedor de retrocesso padrão ou o resolvedor legado obsoleto.
O resolvedor legado ocasionalmente falhará na resolução de dependências. O resolvedor de retrocesso é mais robusto, mas pode levar mais tempo para ser executado em geral.
Você pode continuar usando o resolvedor legado com --resolver=legacy
embora observe que ele está obsoleto e será removido em uma versão futura.