← Назад к вопросам

Где хранить зависимости проекта в Python?

1.3 Junior🔥 161 комментариев
#Скриптинг и программирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Где хранить зависимости проекта в 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-конвейере зависимости устанавливаются на каждом этапе из этих файлов, что гарантирует идентичность сред разработки, тестирования и продакшена.

Где хранить зависимости проекта в Python? | PrepBro