- PVSM.RU - https://www.pvsm.ru -
Так сложилось, что программный пакет Jupyter [1] как бы не в курсе о существовании виртуальных окружений Python, ключевого инструмента изоляции среды в Python. Информация по этой теме в Сети крайне разрознена. В этой статье собраны все известные автору способы обхода / смягчения этой проблемы; надеюсь, кому-то она поможет не тратить столько дней на задачу, которая должна была быть простой.
Архитектура системы Jupyter сложна. Подробнее можно почитать в документации Jupyter [2], в документации jupyter_server [3], в документации jupyter_client [4], а здесь справка тезисно:
Ядро (kernel [5]) — независимый процесс, непосредственно исполняющий код на конкретном языке программирования (используя конкретный экземпляр интерпретатора). Предоставляет сетевой интерфейс с использованием протокола ZeroMQ, используемый в т.ч. для передачи исполняемого кода и получения результатов.
Ядро ipykernel использует IPython [6], программный пакет, реализующий Python с расширенными возможностями интерактивной работы.
Спецификация ядра (kernel spec [7]) — лёгкие метаданные о ядре со ссылкой на нужный интерпретатор. Установка ядра (install kernel) означает установку спецификации ядра; "установленное ядро" не тратит значительные ресурсы хранилища.
Сервер (server) и приложения (web applications) — компоненты, обеспечивающие выполнение пользовательских задач в среде Jupyter.
Сервер — процесс, управляющий пользовательскими сессиями, запущенными ядрами, доступом к файловой системе, предоставляющий REST API к своим функциям.
Большинство приложений являются расширениями сервера — они ведут себя так же, как сервер, но с некоторым добавленным функционалом и пользовательским интерфейсом (как правило — веб-интерфейсом).
Jupyter Notebook, JupyterLab относятся именно к таким приложениям — они дают доступ к редактированию блокнотов и выполнению кода (через ядра).
Могут существовать также приложения, использующие только REST API сервера, но примеры не известны автору.
Чтобы пользователь могу выбрать ядро для использования (а значит, выбрать язык программирования и конкретный экземпляр интерпретатора), сервер Jupyter выполняет поиск доступных спецификаций ядер. В случае Python, выбор конкретного экземпляра интерпретатора важен в частности потому, что это означает и выбор конкретного виртуального окружения. И здесь начинаются проблемы.
"Ядра устанавливается" либо глобально в систему, либо глобально для отдельного пользователя, либо локально в виртуальное окружение. При этом они делят общее пространство имён. Ядра у пользователя имеют приоритет над ядрами глобально в системе, но приоритет ядер в виртуальных окружениях не определён.
Jupyter Core реализует довольно примитивный механизм поиска спецификаций ядер (документация 1 [7], 2 [8]). По умолчанию ищутся только глобально установленные ядра (если само приложение Jupyter исполняется в виртуальном окружении, оно видит локально установленные ядра вместо глобально установленных в системе). Можно через переменную окружения JUPYTER_PATH указать места для поиска локально установленных ядер.
Расширение Jupyter для Visual Studio Code [9] самостоятельно реализует функции приложения. Однако оно имеет более продвинутый механизм поиска спецификаций ядер. Спецификации ядер, размещённые в виртуальном окружении (в директории данных Jupyter share/jupyter), также подбираются и могут быть использованы пользователем. Они должны иметь локально (в отношении виртуального окружения) уникальные имена, однако они делят пространство имён с глобально установленными ядрами, просто с более высоким приоритетом.
Блокнот Jupyter сохраняет ID (name) нужного для его исполнения ядра в своих метаданных (kernelspec.name).
Таким образом, отдельный блокнот требует ядро с определённым именем, это имя ищется в системе глобально. Это мешает переносимости и контролю версий.
В этом разделе описаны варианты использования оригинальной системы Jupyter [1].
Ядро устанавливается локально в виртуальное окружение. Установленные в системе приложения Jupyter настраиваются так, чтобы находить это ядро.
Особенности:
+ Простой порядок работы в случае с единственным виртуальным окружением для каждого блокнота.
Инструкция по настройке проекта (однократной):
Добавьте пакет ipykernel в зависимости Python (requirements.txt / pyproject.toml ...).
Выберите локальный ID для ядра (например, python3_venv).
Не забывайте записывать ID ядра в каждый блокнот в метаданные (kernelspec.name).
Инструкция по установке проекта (в виртуальное окружение, после установки зависимостей Python):
Установите ядро, связанное с виртуальным окружением, в директорию этого виртуального окружения. Укажите ID ядра, используемый блокнотами (см. инструкцию по настройке проекта), вместо NAME. Опционально укажите отображаемое имя ядра вместо DISPLAY_NAME (если не укажете, будет использовано ID ядра). ID/имя ядра нужно, чтобы позже найти его через интерфейс установленного в системе приложения Jupyter.
python -m ipykernel --sys-prefix --name NAME [--display-name DISPLAY_NAME]
Примечание: Какое-то ядро python3 устанавливается в виртуальное окружение уже при установке ipykernel. Оно ссылается на интерпретатор Python как python; видимо, из-за этого код Jupyter, работающий вне виртуального окружения, запускает установленный в системе интерпретатор Python вместо соответствующего виртуальному окружению. Поэтому это ядро, по-видимому, бесполезно. См. также примечание в инструкции по использованию в разделе Расширение Jupyter для Visual Studio Code.
Опционально, заранее сохраните в переменную окружения JUPYTER_PATH путь к данным Jupyter в виртуальном окружении <path> — см. п. 1 в инструкции по использованию.
Windows (PowerShell):
[System.Environment]::SetEnvironmentVariable('JUPYTER_PATH', "<path>;$env:JUPYTER_PATH", 'User')
UNIX (sh):
echo 'export JUPYTER_PATH="<path>:$JUPYTER_PATH"' >> ~/.profile
Инструкция по использованию:
Если при выполнении инструкции по установке Вы не сохранили в переменную окружения JUPYTER_PATH путь к данным Jupyter в виртуальном окружении, этот путь нужно добавить в переменную окружения сейчас. Добавьте в переменную окружения JUPYTER_PATH абсолютный путь (далее обозначаемый <path>) $VIRTUAL_ENV/share/jupyter, где следует заменить $VIRTUAL_ENV на путь к директории, где развёрнуто виртуальное окружение. Для инструментов venv [10], virtualenv [11] можно просто в активном виртуальном окружении использовать подстановку переменной окружения VIRTUAL_ENV (активное виртуальное окружение не повлияет на дальнейшие шаги).
Windows (PowerShell):
$env:JUPYTER_PATH = "<path>;$env:JUPYTER_PATH"
UNIX (sh):
export JUPYTER_PATH="<path>:$JUPYTER_PATH"
Запустите установленное в системе приложение Jupyter, например, Jupyter Notebook. (Если Вы всё ещё в виртуальном окружении, всё равно запустится именно приложение, установленное в систему, т.к. Вы не устанавливали приложения Jupyter в виртуальное окружение).
jupyter notebook
Используйте приложение Jupyter. Не забывайте выбирать нужное ядро (которое Вы установили локально) при работе с кодом Python.
Нужные приложения Jupyter (или только сервер, если используется приложение, подключаемое по REST API) устанавливаются в виртуальное окружение.
Особенности:
+ Простой порядок работы в случае с единственным виртуальным окружением для проекта.
− Высокий расход ресурсов хранилища; пакет notebook версии 7.4 со всеми зависимостями занимает порядка 264 МБ 12 тысячами файлов.
− Потенциальные проблемы с более сложными рабочими процессами из-за изоляции среды Jupyter от других проектов.
Инструкция по настройке проекта (однократной):
Опционально, добавьте нужные приложения Jupyter (например, пакет notebook) в список зависимостей Python (requirements.txt / pyproject.toml ...).
Инструкция по установке проекта (в виртуальное окружение, после установки зависимостей Python):
Если Вы не добавили приложения Jupyter в зависимости Python.
Установите нужные приложения Jupyter (или только сервер Jupyter, если используется приложение, подключаемое по REST API) в виртуальное окружение.
Далее показан пример для веб-приложения Jupyter Notebook (пакет notebook).
pip install -U notebook
Инструкция по использованию:
В виртуальном окружении запустить нужное приложение Jupyter:
Далее показан пример для веб-приложения Jupyter Notebook (пакет notebook).
jupyter notebook
Использовать приложение Jupyter — ядро, выбранное по умолчанию, и будет актуально в виртуальном окружении.
См. другой способ в подразделе Использование локальных ядер.
Ядро устанавливается в систему (для пользователя или глобально). Установленные в системе приложения Jupyter видят это ядро без дополнительной настройки.
Особенности:
+ Относительно простой порядок работы в случае с единственным виртуальным окружением для каждого блокнота.
− Необходимо обеспечить уникальность ID ядра для проекта. При добавлении условно уникальной строки в ID оно может стать нечитаемым.
− Если необходимо иметь несколько ядер для одного блокнота (например, для нескольких виртуальных окружений), необходимо применять локальные правки к блокноту, что существенно усложняет контроль версий.
− Установленные спецификации ядер остаются в системе глобально и захламляют систему.
Инструкция по настройке проекта (однократной):
Добавьте пакет ipykernel в зависимости Python (requirements.txt / pyproject.toml ...).
Выберите ID для ядра, глобально уникальный в возможных условиях развёртывания (например, <project-name>-<unique-id>, где <unique-id> — достаточно длинная уникальная строка).
Не забывайте записывать ID ядра в каждый блокнот в метаданные (kernelspec.name).
Инструкция по установке проекта (в виртуальное окружение, после установки зависимостей Python):
Установите ядро, связанное с виртуальным окружением, в систему. Укажите ID ядра, используемый блокнотами (см. инструкцию по настройке проекта), вместо NAME. Опционально укажите отображаемое имя ядра вместо DISPLAY_NAME (если не укажете, будет использовано ID ядра). ID/имя ядра нужно, чтобы позже найти его через интерфейс установленного в системе приложения Jupyter.
python -m ipykernel --user --name NAME [--display-name DISPLAY_NAME]
Эта команда устанавливает ядро для текущего пользователя. Опционально Вы можете установить ядро глобально, убрав опцию --user.
Инструкция по удалению проекта (помимо других действий):
Удалите ядро, связанное с виртуальным окружением, из системы. Укажите ID ядра, используемый блокнотами (см. инструкцию по настройке проекта), вместо NAME.
jupyter kernelspec uninstall NAME
Инструкция по использованию:
Запустите установленное в системе приложение Jupyter, например, Jupyter Notebook. (Если Вы всё ещё в виртуальном окружении, всё равно запустится именно приложение, установленное в систему, т.к. Вы не устанавливали приложения Jupyter в виртуальное окружение).
jupyter notebook
Используйте приложение Jupyter. Не забывайте выбирать нужное ядро (которое Вы установили в систему, по его уникальному ID/имени) при работе с кодом Python.
В этом разделе описано использование расширения Jupyter для Visual Studio Code [9].
Ядро устанавливается локально в виртуальное окружение. Установленные в системе приложения Jupyter настраиваются так, чтобы находить это ядро.
Особенности:
+ Простой порядок работы в случае с единственным ядром для каждого блокнота.
− Несовместимость блокнотов, созданных в расчёте на использование этого подхода, со многими другими способами изоляции в Jupyter (кроме установки приложений Jupyter в локальные окружения).
− Ограниченный функционал и нестабильность расширения Jupyter для Visual Studio Code.
Инструкция по настройке проекта (однократной):
Добавьте пакет ipykernel в зависимости Python (requirements.txt / pyproject.toml ...).
Инструкция по использованию:
Запустите Visual Studio Code.
Откройте директорию проекта в VS Code.
Если VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь.
Иначе укажите [12] своё виртуальное окружение самостоятельно.
Используйте VS Code с расширением Jupyter. Не забывайте при открытии любого блокнота проверять, что выбрано корректное ядро Jupyter (принадлежащее корректному виртуальному окружению). (Кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу области содержимого вкладки; по умолчанию Вы увидите название выбранного виртуального окружения; если ядро не выбрано, на кнопке написано Select Kernel.)
Примечание: Каким-то неизвестным автору образом расширение Jupyter для Visual Studio Code обходит проблему, описанную в примечании к инструкции по установке в подразделе Использование локальных ядер, не изменяя спецификацию ядра.
Автор: asrelo
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/432951
Ссылки в тексте:
[1] Jupyter: https://jupyter.org/
[2] документации Jupyter: https://docs.jupyter.org/en/stable/projects/architecture/content-architecture.html
[3] документации jupyter_server: https://jupyter-server.readthedocs.io/en/stable/
[4] документации jupyter_client: https://jupyter-client.readthedocs.io/en/stable/
[5] kernel: https://docs.jupyter.org/en/latest/projects/kernels.html#kernels
[6] IPython: https://ipython.org/
[7] kernel spec: https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs
[8] 2: https://docs.jupyter.org/en/stable/use/jupyter-directories.html#data-files
[9] Расширение Jupyter для Visual Studio Code: https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter
[10] venv: https://docs.python.org/3/library/venv.html
[11] virtualenv: https://virtualenv.pypa.io/en/stable/
[12] укажите: https://code.visualstudio.com/docs/python/environments#_working-with-python-interpreters
[13] Источник: https://habr.com/ru/articles/954598/?utm_source=habrahabr&utm_medium=rss&utm_campaign=954598
Нажмите здесь для печати.