Разделение зависимостей для локальной разработки и рабочего сервера (pip, requirements.txt)
Имеем
- Локальный проект, локальное виртуальное пространство
- Git репозиторий
- Рабочий проект (сервер), рабочее виртуальное пространство
Для создания зависимостей очень удобно использовать pip freeze > requirements.txt на локалке. Через git закинул на рабочий сервер, а далее установил все зависимости.
Но сейчас решил потестировать различные модули и в локальное виртуальное пространство установил кучу python'ских пакетов, которые обязательно попадут в requirements.txt, а затем в рабочее окружение. В действительности они там не нужны.
Есть ли готовое решения для управления двумя версиями зависимостей? Один для рабочего окружения, другой для локального использования. Может какой нибудь менеджер существует?
Ответы (3 шт):
Вот один вариант разделения и наследования зависимостей, через включение файлов зависимостей.
Создаете файл runtime-requirements.txt с зависимостями для прода.
Для локальной разработки создаете dev-requirements.txt и туда в дополнение к зависимостям используемым чисто для разработки включаете строку:
-r runtime-requirements.txt
Она заставит pip включить все зависимости из runtime-requirements.txt при выполнении pip install -r dev-requirements.txt.
Оба файла хранятся в git, и меняются хоть вручную, хоть с помощью pip freeze при добавлении новых зависимостей.
Обычно я использую даже три файла: runtime.txt -> test.txt -> dev.txt.
test.txt - для использования на CI (всякие Hamcrest, testcontainers, factoryboy и прочее). dev.txt - ipdb, django-debug-toolbar и т.п.
Как вариант, можно устанавливать зависимости прямо в рантайме. У меня есть библиотечка для этого.
Устанавливается так:
pip install instld
Когда она уже установлена, можно прямо в рантайме поставить любую библиотеку:
import installed
with installed('some_package') as context:
import some_module
Но основное удобство в том, что вы становитесь более не привязаны к конкретным сочетаниям версий библиотек. В одном рантайме могут сосуществовать две разные версии одной и той же библиотеки. Или можно параллельно использовать две несовместимые либы.
В случае использования данной библиотеки вы можете передавать ожидаемые версии зависимостей в виде переменных среды.
Как упомянули в комментариях, можно использовать poetry.
Вместо отдельных файлов зависимостей там используется общий файл проекта pyproject.toml, в котором могут быть отдельные разделы (группы) для обязательных зависимостей (для "боевого" окружения) и, например, для разработки. Раньше было разделение только на боевые/"разработческие" зависимости, сейчас можно создавать в принципе неограниченное количество групп.
Пример:
> poetry new test-project # Создаем новый пустой проект
Created package test_project in test-project
> cd test-project
> ls
pyproject.toml README.md test_project tests
> poetry add requests # Добавляем "боевую зависимость"
> poetry add --group dev black # Добавляем "девелоперскую" зависимость
> poetry add --dev black # То же самое, но в стиле более старых версий poetry (напишет, что этот вариант deprecated)
> poetry add --group test pytest # Добавляем зависимость для тестирования
Для инициализации pyproject.toml в уже существующем проекте вместо poetry new нужно использовать poetry init.
Смотрим pyproject.toml:
[tool.poetry]
name = "test-project"
version = "0.1.0"
description = ""
authors = ["user <[email protected]>"]
readme = "README.md"
packages = [{include = "test_project"}]
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.29.0"
[tool.poetry.group.dev.dependencies]
black = "^23.3.0"
[tool.poetry.group.test.dependencies]
pytest = "^7.3.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Локально когда вы добавили первую зависимость вам автоматом создало виртуальное окружение и установило зависимость туда.
Удаление зависимостей - через команду poetry remove .... Можно править и файл pyproject.toml, но после изменений нужно выполнять команду poetry update, чтобы зависимости установились/удалились.
Дальше, если вы только выкачали проект с github, и хотите создать виртуальное окружение с установкой всех зависимостей, выполняете команду (установятся все группы зависимостей, кроме обозначенных необязательными):
poetry install
Если нужны только основные ("боевые") зависимости, вместо этого нужно выполнить команду
poetry install --only-root
Если нужно установить только основные и тестовые зависимости (но не нужны всякие форматтеры), нужна команда
poetry install --with test
Документация по управлению зависимостями: Managing dependencies
Ну и в целом как работать с poetry:
poetry run python some_script.py
- запустит команду в виртуальном окружении, но без постоянной активации виртуального окружения.
Это удобно, например, для запуска команд из окружения в CI:
- name: Test with pytest
run: |
poetry run pytest --cov=./
Аналог активации виртуального окружения как при работе с venv/virtualenv выполняется командой
poetry shell
Деактивация окружения - командой exit (без poetry).