Современные среды Python - управление зависимостями и рабочими пространствами

После того как вы пройдете через муки настройки среды Python для одного приложения типа "hello world", вам придется пройти через еще более сложный процесс выяснения того, как управлять несколькими средами для нескольких проектов на Python. Некоторые из этих проектов могут быть новыми, а другие представляют собой груды кода десятилетней давности. К счастью, существует ряд инструментов, позволяющих упростить управление зависимостями и рабочими пространствами.

В этой статье мы рассмотрим доступные инструменты для управления зависимостями и рабочими пространствами, чтобы решить следующие проблемы:

  1. Установка и переключение между различными версиями Python на одной машине
  2. Управление зависимостями и виртуальными окружениями
  3. Воспроизведение окружений

Полное руководство по Python:

  1. Современные среды Python - управление зависимостями и рабочим пространством (эта статья!)
  2. Тестирование на Python
  3. Современная разработка на основе тестов в Python
  4. Качество кода на Python
  5. Проверка типов в Python
  6. Документирование кода и проектов на Python
  7. Рабочий процесс проекта на Python

Установка Python

Хотя вы можете загрузить и установить Python из официальных бинарников или с помощью менеджера пакетов вашей системы, вам следует избегать этих подходов, если только вам не посчастливилось использовать одну и ту же версию Python для всех ваших текущих и будущих проектов. Поскольку это, скорее всего, не так, мы рекомендуем устанавливать Python с помощью pyenv.

pyenv - это инструмент, который упрощает установку и переключение между различными версиями Python на одной машине. Он сохраняет системную версию Python, которая необходима для корректной работы некоторых операционных систем, и в то же время позволяет легко переключать версии Python в зависимости от требований конкретного проекта.

К сожалению, pyenv не работает под Windows вне Windows Subsystem for Linux. Посмотрите pyenv-win, если это для вас так.

После установки вы можете легко установить определенную версию Python следующим образом:

$ pyenv install 3.8.5
$ pyenv install 3.8.6
$ pyenv install 3.9.0
$ pyenv install 3.10.2

$ pyenv versions
* system
  3.8.5
  3.8.6
  3.9.0
  3.10.2

Затем вы можете установить глобальную версию Python следующим образом:

$ pyenv global 3.8.6

$ pyenv versions
  system
  3.8.5
* 3.8.6 (set by /Users/michael/.pyenv/version)
  3.9.0
  3.10.2

$ python -V
Python 3.8.6

Помните, что это не изменяет и не влияет на Python на системном уровне.

Аналогичным образом можно установить интерпретатор Python для текущей папки:

$ pyenv local 3.10.2

$ pyenv versions
  system
  3.8.5
  3.8.6
  3.9.0
* 3.10.2 (set by /Users/michael/repos/testdriven/python-environments/.python-version)

$ python -V
Python 3.10.2

Теперь каждый раз, когда вы запускаете Python в этой папке, будет использоваться версия 3.10.2.

Если вы обнаружите, что не можете переключаться между разными версиями Python, возможно, вам нужно изменить конфигурацию профиля оболочки. Подробности см. в руководстве по установке .

Управление зависимостями

В этом разделе мы рассмотрим несколько инструментов для управления зависимостями, а также виртуальными средами.

venv + pip

venv и pip (package installer for python), поставляемые с большинством версий Python, являются наиболее популярными инструментами для управления виртуальными средами и пакетами соответственно. Они довольно просты в использовании.

Виртуальные среды предотвращают конфликты версий зависимостей. Вы можете установить разные версии одной и той же зависимости в разных виртуальных средах.

Вы можете создать новую виртуальную среду под названием my_venv внутри текущей папки следующим образом:

$ python -m venv my_venv

После создания окружения его необходимо активировать, выполнив скрипт activate внутри виртуального окружения:

$ source my_venv/bin/activate
(my_venv)$

Для деактивации выполните deactivate. Затем, для повторной активации, выполните source my_venv/bin/activate в корневом каталоге проекта.

Запуск which python при активированной виртуальной среде вернет путь к интерпретатору Python внутри виртуальной среды:

(my_venv)$ which python

/Users/michael/repos/testdriven/python-environments/my_venv/bin/python

Вы можете установить пакеты, локальные для вашего проекта, запустив pip install <package-name> с активированной виртуальной средой:

(my_venv)$ python -m pip install requests

pip загружает пакет из PyPI (Python Package Index), а затем делает его доступным для интерпретатора Python внутри виртуальной среды.

Для воспроизводимости среды обычно требуется хранить список необходимых пакетов для проекта в файле requirements.txt. Вы можете вручную создать этот файл и добавить их или использовать команду pip freeze для его генерации:

(my_venv)$ python -m pip freeze > requirements.txt

(my_venv)$ cat requirements.txt
certifi==2021.10.8
charset-normalizer==2.0.12
idna==3.3
requests==2.27.1
urllib3==1.26.8

Хотите взять только зависимости верхнего уровня (например, requests==2.27.1)? Посмотрите pip-chill.

Хотя и venv, и pip просты в использовании, они очень примитивны по сравнению с более современными инструментами, такими как Poetry и Pipenv. venv и pip ничего не знают о версии Python, с которой работают. Вам придется управлять всеми зависимостями и виртуальными окружениями вручную. Вам придется самостоятельно создавать и управлять файлом requirements.txt. Более того, вам придется вручную разделять зависимости разработки (pytest, black, isort, ...) и производства (Flask, Django, FastAPI, ...) с помощью файла requirements-dev.txt.

requirements-dev.txt:

# prod
-r requirements.txt

# dev
black==22.1.0
coverage==6.3.2
flake8==4.0.1
ipython==8.0.1
isort==5.10.1
pytest-django==4.5.2
pytest-cov==3.0.0
pytest-xdist==2.5.0
pytest-mock==3.7.0

requirements.txt:

Django==4.0.2
django-allauth==0.49.0
django-crispy-forms==1.14.0
django-rq==2.5.1
django-rq-email-backend==0.1.3
gunicorn==20.1.0
psycopg2-binary==2.9.3
redis==4.1.4
requests==2.27.1
rq==1.10.1
whitenoise==6.0.0

Poetry и Pipenv объединяют функциональность venv и pip. Они также позволяют легко разделять зависимости разработки и производства, а также обеспечивают детерминированные сборки с помощью файла блокировки. Они хорошо работают с pyenv.

Файлы блокировки фиксируют (или блокируют) все версии зависимостей во всем дереве зависимостей.

Poetry

Poetry - это, пожалуй, самый многофункциональный инструмент управления зависимостями для Python. Он поставляется с мощным CLI, используемым для создания и управления проектами Python. После установки, чтобы создать новый проект, выполните следующие действия:

$ poetry new sample-project
$ cd sample-project

При этом будут созданы следующие файлы и папки:

sample-project
├── README.rst
├── pyproject.toml
├── sample_project
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_sample_project.py

Управление зависимостями осуществляется внутри файла pyproject.toml:

[tool.poetry]
name = "sample-project"
version = "0.1.0"
description = ""
authors = ["John Doe <john@doe.com>"]

[tool.poetry.dependencies]
python = "^3.10"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

Подробнее о pyproject.toml, новом файле конфигурации пакетов Python, который рассматривает "каждый проект как пакет", читайте в статье What the heck is pyproject.toml?.

Чтобы добавить новую зависимость, просто выполните:

$ poetry add [--dev] <package name>

Флаг --dev указывает на то, что зависимость предназначена только для использования в режиме разработки. Зависимости для разработки не устанавливаются по умолчанию.

Например:

$ poetry add flask

Это скачает и установит Flask с PyPI в виртуальную среду, управляемую Poetry, добавит его вместе со всеми подзависимостями в файл poetry.lock и автоматически добавит его (зависимость верхнего уровня) в pyproject.toml:

[tool.poetry.dependencies]
python = "^3.10"
Flask = "^2.0.3"

Обратите внимание на ограничение версии: "^2.0.3".

Чтобы запустить команду внутри виртуальной среды, добавьте к ней префикс poetry run. Например, чтобы запустить тесты с помощью pytest:

$ poetry run python -m pytest

poetry run <command> будет запускать команды внутри виртуальной среды. Однако это не активирует виртуальную среду. Чтобы активировать виртуальную среду Poetry, нужно выполнить команду poetry shell. Чтобы деактивировать ее, достаточно выполнить команду exit. Следовательно, вы можете активировать виртуальную среду перед началом работы над проектом и деактивировать ее по окончании работы или использовать poetry run <command> на протяжении всей разработки.

Наконец, Poetry хорошо работает с pyenv. Просмотрите Managing environments из официальной документации, чтобы узнать больше об этом.

Pipenv

Pipenv пытается решить те же проблемы, что и Poetry:

  1. Управление зависимостями и виртуальными окружениями
  2. Воспроизведение окружений

После установки, чтобы создать новый проект с помощью Pipenv, выполните:

$ mkdir sample-project
$ cd sample-project
$ pipenv --python 3.10.2

Это создаст новую виртуальную среду и добавит Pipfile в проект:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.10"

А Pipfile работает так же, как и файл pyproject.toml в стране Поэзии.

Вы можете установить новую зависимость следующим образом:

$ pipenv install [--dev] <package name>

Флаг --dev указывает на то, что зависимость предназначена только для использования в режиме разработки. Зависимости для разработки не устанавливаются по умолчанию.

Например:

$ pipenv install flask

Как и в случае с Poetry, Pipenv загружает и устанавливает Flask внутри виртуальной среды, фиксирует все подзависимости в файле Pipfile.lock и добавляет зависимость верхнего уровня в Pipfile.

Чтобы запустить скрипт в виртуальной среде, управляемой Pipenv, необходимо запустить его с помощью команды pipenv run. Например, чтобы запустить тесты с помощью команды pytest, выполните:

$ pipenv run python -m pytest

Как и Poetry, pipenv run <command> будет выполнять команды из виртуальной среды. Чтобы активировать виртуальное окружение Pipenv, нужно выполнить команду pipenv shell. Чтобы деактивировать ее, можно выполнить exit.

Pipenv также хорошо работает с pyenv. Например, когда вы хотите создать виртуальное окружение из версии Python, которая у вас еще не установлена, он спросит, хотите ли вы установить ее сначала с помощью pyenv:

$ pipenv --python 3.7.5

Warning: Python 3.7.5 was not found on your system…
Would you like us to install CPython 3.7.5 with Pyenv? [Y/n]: Y

Рекомендации

Какую использовать?

  1. venv и pip
  2. Poetry
  3. Pipenv

Рекомендуется начать с venv и pip. С ними проще всего работать. Ознакомьтесь с ними и самостоятельно определите, в чем они хороши, а в чем нет.

Poetry или Pipenv?

Поскольку они оба решают одни и те же проблемы, все сводится к личным предпочтениям.

Примечания:

  1. Публикация на PyPI намного проще с Poetry, так что если вы создаете пакет для Python, выбирайте Poetry.
  2. Оба проекта довольно медлительны, когда дело доходит до разрешения зависимостей, так что если вы используете Docker, то лучше воздержаться от них обоих.
  3. С точки зрения разработки с открытым исходным кодом, Poetry движется быстрее и, возможно, лучше реагирует на отзывы пользователей.

Дополнительные инструменты

Помимо вышеперечисленных инструментов, обратите внимание на следующие, которые помогут установить и переключиться между различными версиями Python на одной машине, управлять зависимостями и виртуальными средами, а также воспроизводить среды:

  1. Docker - это платформа для создания, развертывания и управления контейнерными приложениями. Она идеально подходит для создания воспроизводимых сред.
  2. Conda, которая довольно популярна в сообществах data science и machine learning, может помочь с управлением зависимостями и виртуальными средами, а также воспроизводимыми средами.
  3. Когда вам нужно просто упростить переключение между виртуальными окружениями и управлять ими в одном месте virtualenvwrapper и pyenv-virtualenv, плагин для pyenv, стоит посмотреть.
  4. pip-tools упрощает управление зависимостями и воспроизводимость среды. Часто используется вместе с venv.
  Python Version Dependency Management Virtual Environment Environment Reproducibility
pyenv
venv + pip
venv + pip-tools
Poetry
Pipenv
Docker
Conda

Управление проектом

Давайте рассмотрим, как управлять проектом Flask с помощью pyenv и Poetry.

Сначала создайте новый каталог под названием "flask_example" и переместитесь в него:

$ mkdir flask_example
$ cd flask_example

Во-вторых, установите версию Python для проекта с помощью pyenv:

$ pyenv local 3.10.2

Далее инициализируйте новый проект Python с помощью Poetry:

$ poetry init

Package name [flask_example]:
Version [0.1.0]:
Description []:
Author [Your name <your@email.com>, n to skip]:
License []:
Compatible Python versions [^3.10]:

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Do you confirm generation? (yes/no) [yes]

Добавить flask:

$ poetry add flask

В последнюю очередь добавьте pytest в качестве зависимости разработки:

$ poetry add --dev pytest

Теперь, когда у нас есть базовая среда, мы можем написать тест для одной конечной точки.

Добавьте файл с именем test_app.py:

import pytest

from app import app


@pytest.fixture
def client():
    app.config['TESTING'] = True

    with app.test_client() as client:
        yield client


def test_health_check(client):
    response = client.get('/health-check/')

    assert response.status_code == 200

После этого добавьте базовое приложение Flask в новый файл под названием app.py:

from flask import Flask

app = Flask(__name__)


@app.route('/health-check/')
def health_check():
    return 'OK'


if __name__ == '__main__':
    app.run()

Теперь, чтобы запустить тесты, выполните:

$ poetry run python -m pytest

И вы можете запустить сервер разработки следующим образом:

$ poetry run python -m flask run

Команда poetry run запускает команду внутри виртуальной среды Poetry.

Заключение

В этой статье были рассмотрены наиболее популярные инструменты для решения следующих проблем, связанных с управлением зависимостями и рабочим пространством:

  1. Установка и переключение между различными версиями Python на одной машине
  2. Управление зависимостями и виртуальными окружениями
  3. Воспроизведение окружений

Меньше значения имеет то, какие именно инструменты вы используете в своем рабочем процессе, а больше то, что вы способны решить эти проблемы. Выбирайте те инструменты, которые облегчают вам разработку на Python. Экспериментируйте. Они существуют для того, чтобы облегчить ваш ежедневный рабочий процесс разработки, чтобы вы могли стать настолько продуктивными, насколько это возможно. Попробуйте все из них и используйте те, которые подходят для вашего стиля разработки. Никаких суждений.

Счастливого кодирования.

Полное руководство по Python:

  1. Современные среды Python - управление зависимостями и рабочим пространством (эта статья!)
  2. Тестирование на Python
  3. Современная разработка на основе тестов в Python
  4. Качество кода на Python
  5. Проверка типов в Python
  6. Документирование кода и проектов на Python
  7. Рабочий процесс проекта на Python
Вернуться на верх