Где хранить зависимости проекта в Python?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Где хранить зависимости проекта в Python: DevOps-перспектива
Ключевое правило DevOps: зависимости должны храниться в системе контроля версий (VCS) вместе с исходным кодом, но не как распакованные пакеты, а в виде декларативных файлов, которые можно воспроизвести в любой среде. Вот основные подходы:
1. Файл requirements.txt (классический подход)
Это стандартный файл, генерируемый pip. В DevOps мы различаем два типа:
- Для разработки (
requirements-dev.txt): содержит все зависимости, включая инструменты тестирования, линтинга, etc. - Для продакшена (
requirements.txt): только минимально необходимые пакеты для работы приложения.
# requirements.txt
Django==4.2.0
psycopg2-binary==2.9.5
redis==4.5.4
# requirements-dev.txt
-r requirements.txt
pytest==7.3.1
black==23.3.0
mypy==1.2.0
Проблема: не фиксирует зависимости второго уровня (transitive dependencies), что может приводить к "дрейфу зависимостей".
2. Файлы Pipfile и Pipfile.lock (современный подход)
Инструмент pipenv использует эту пару файлов:
Pipfile: человекочитаемая декларация зависимостей (аналогично package.json в Node.js)Pipfile.lock: точный снапшот всех зависимостей с хэшами для гарантированной воспроизводимости
# Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
django = "==4.2.0"
celery = {version = ">=5.2.0", extras = ["redis"]}
[dev-packages]
pytest = "*"
black = "==23.3.0"
[requires]
python_version = "3.11"
Преимущество: полная детерминированность сборки благодаря lock-файлу.
3. Файл pyproject.toml (современный стандарт PEP 621)
Стандарт, который объединяет конфигурацию проекта, сборку и зависимости:
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "my-project"
dependencies = [
"Django>=4.2",
"psycopg2>=2.9",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"black>=23.0",
]
Для фиксации версий используется poetry с poetry.lock или uv с uv.lock.
4. Рекомендации с точки зрения DevOps
В системе контроля версий храним:
pyproject.tomlилиPipfile(декларация зависимостей)- Соответствующий lock-файл (
poetry.lock,Pipfile.lock,requirements.txtс фиксированными версиями) .python-versionилиruntime.txtдля указания версии Python
Чего НЕ делать:
- Никогда не хранить виртуальное окружение (.venv/) в репозитории
- Не коммитить сгенерированные файлы
__pycache__/,.pyc - Избегать "заморозки" через
pip freeze > requirements.txtбез предварительной очистки
5. Стратегия управления зависимостями в CI/CD
# Пример GitLab CI pipeline
stages:
- test
- build
.test_template: &test_template
image: python:3.11-slim
before_script:
- python -m pip install --upgrade pip
- pip install poetry # или uv
- poetry install --no-root # для dev-зависимостей
test:
<<: *test_template
script:
- poetry run pytest
build-docker:
image: docker:latest
script:
- docker build -t myapp:${CI_COMMIT_SHORT_SHA} .
6. Продвинутые практики
Контейнеризация: зависимости фиксируются в Docker-образе:
FROM python:3.11-slim
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN pip install poetry && poetry install --no-dev --no-root
COPY . .
Артефакты: в некоторых случаях lock-файлы можно генерировать в CI и хранить как артефакты сборки.
Security scanning: интеграция инструментов типа Safety, Dependabot или Trivy для сканирования уязвимостей в зависимостях.
Вывод: В современном Python-стеке я рекомендую использовать pyproject.toml с poetry или uv для управления зависимостями. Lock-файл должен обязательно коммититься в репозиторий для обеспечения воспроизводимости сборок. В DevOps-конвейере зависимости устанавливаются на каждом этапе из этих файлов, что гарантирует идентичность сред разработки, тестирования и продакшена.