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

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

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

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

The Complete Python Guide:

  1. Modern Python Environments - dependency and workspace management (this article!)
  2. Testing in Python
  3. Modern Test-Driven Development in Python
  4. Python Code Quality
  5. Python Type Checking
  6. Documenting Python Code and Projects
  7. Python Project Workflow

Установка 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 versions
* system
  3.8.5
  3.8.6
  3.9.0

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

$ pyenv global 3.8.6

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

$ python -V
Python 3.8.6

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

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

$ pyenv local 3.9.0

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

$ python -V
Python 3.9.0

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

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

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

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==2020.6.20
chardet==3.0.4
idna==2.10
requests==2.24.0
urllib3==1.25.11

Хотите взять только зависимости верхнего уровня (например, requests==2.24.0)? Посмотрите 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==20.8b1
coverage==5.0.3
flake8==3.7.9
ipython==7.12.0
isort==4.3.21
pytest-django==3.8.0
pytest-cov==2.8.1
pytest-xdist==1.31.0
pytest-mock==3.1.1

requirements.txt:

Django==3.0.8
django-allauth==0.41.0
django-crispy-forms==1.8.1
django-rq==2.2.0
django-rq-email-backend==0.1.3
gunicorn==20.0.4
psycopg2-binary==2.8.4
redis==3.4.1
requests==2.22.0
rq==1.2.2
whitenoise==5.0.1

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.8"

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

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

Подробнее о pyproject.toml, новом файле конфигурации пакетов Python, который рассматривает "каждый проект как пакет", читайте в заметке Что это за хрень - pyproject.toml?.

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

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

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

Например:

$ poetry add flask

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

[tool.poetry.dependencies]
python = "^3.8"
flask = "^1.1.2"

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

Чтобы выполнить команду внутри виртуальной среды, добавьте к ней префикс 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. Managing dependencies and virtual environments
  2. Reproducing environments

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

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

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

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

[dev-packages]

[packages]

[requires]
python_version = "3.8"

A 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 and pip
  2. Poetry
  3. Pipenv

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

Поэзия или пипенв?

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

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

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

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

  1. Docker — это платформа для создания, развертывания и управления контейнерными приложениями. Он идеально подходит для создания воспроизводимых сред. Conda, довольно популярная в сообществе специалистов по данным и машинному обучению, может помочь в управлении зависимостями и виртуальными средами, а также в воспроизведении сред. Когда вам нужно просто упростить переключение между виртуальными средами и управлять ими в одном месте, стоит обратить внимание на virtualenvwrapper и pyenv-virtualenv , плагин pyenv. pip-tools упрощает управление зависимостями и воспроизводимость среды. Это часто сочетается с venv.

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

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

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

$ mkdir flask_example
$ cd flask_example

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

$ pyenv local 3.8.6

Далее, инициализируйте новый проект 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.7]:  >3.7

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]

Добавить колбу:

$ 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. Installing and switching between different versions of Python on the same machine
  2. Managing dependencies and virtual environments
  3. Reproducing environments

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

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

The Complete Python Guide:

  1. Modern Python Environments - dependency and workspace management (this article!)
  2. Testing in Python
  3. Modern Test-Driven Development in Python
  4. Python Code Quality
  5. Python Type Checking
  6. Documenting Python Code and Projects
  7. Python Project Workflow
Вернуться на верх