Использование пакета Golang в Python с помощью Gopy
В этой статье мы расскажем о простом способе использования возможностей пакетов Golang в приложениях Python.
@Golang_google – бесплатный обучающий канал по Golang в телеграм от профи!
История
Работая над CLI-инструментом на базе Python, мы столкнулись с необходимостью статической проверки запросов PromQL. Но мы не смогли найти ни одного пакета Python для этого. Были некоторые пакеты, которые делали это, но набор правил, используемых для проверки, не соответствовал оригинальной проверке, выполняемой самим Prometheus.
Таким образом, у нас остается два варианта:
- Создать Python-версию парсера PromQL на базе Golang, используемого в Prometheus.
- Или использовать существующий пакет Golang.
Первый вариант был не очень желателен. Очевидная причина в том, что это “изобретение колеса”. Но, кроме того, любой новый пакет, имитирующий существующий пакет Go, всегда должен будет “идти в ногу” с оригиналом. Это ненужные накладные расходы на обслуживание.
Поэтому более предпочтительным вариантом является повторное использование существующего пакета Go. Мы решили, что это сэкономит нам много времени, и мы будем иметь дело непосредственно с PromQL. Кроме того, это откроет двери для многих других функций экосистемы Prometheus (которая в основном находится на Golang).
Но по разным причинам мы не стали использовать парсер PromQL от Prometheus. Вместо этого мы использовали парсер MetricsQL от VictoriaMetrics. VictoriaMetrics – это еще одна TSDB с открытым исходным кодом, аналогичная Prometheus, а MetricsQL – это ее язык запросов. MetricsQL является обратно совместимым расширением PromQL. Итак, это подходит для нашего случая использования – статической валидации запросов PromQL.
Решение
Когда речь идет об использовании кода Go в проекте Python, существует несколько способов сделать это. Один из распространенных подходов заключается в создании файла разделяемых объектов (SO), содержащего скомпилированный код Go, который затем может быть импортирован непосредственно в Python.
Этот метод относительно прост для небольших скриптов. Однако он может стать сложным при работе с большими приложениями, которые необходимо упаковать для использования другими пользователями. Кроме того, такой подход требует знания языков Go и C, что может оказаться сложной задачей для разработчиков Python, не знакомых с этими языками.
Для решения этих проблем существует несколько библиотек, которые упрощают процесс включения кода Go в проекты Python. Одной из самых популярных является Gopy, которая позволяет компилировать код Go в модуль Python с помощью простого интерфейса командной строки.
Давайте углубимся во все этапы, связанные с использованием gopy. Если вы хотите следовать за нами – создайте пустой рабочий каталог, настройте новое виртуальное окружение и активируйте его.
Шаги, которые необходимо выполнить
Необходимые шаги:
1.Клонируйте репозиторий metricsQL
git clone git@github.com:VictoriaMetrics/metricsql.git --depth 1
cd metricsql
Эта команда клонирует репозиторий metricsQL с GitHub на вашу локальную машину. Флаг –depth 1 указывает Git’у клонировать только самый последний коммит, что значительно ускорит процесс клонирования.
2.Установите gopy и необходимые зависимости для сборки Python
go install github.com/go-python/gopy@latest
pip3 install pybindgen wheel
pybindgen используется внутри gopy. Позже мы будем использовать пакет wheel для создания файла .whl.
3.Создайте модуль Python
gopy build --output=py_metricsql -vm=python3 .
Эта команда построит модуль Python из кода Go в текущем каталоге. Флаг –output=py_metricsql указывает gopy на вывод собранного модуля в каталог py_metricsql. Флаг –vm=python3 указывает gopy на сборку модуля для Python 3. При этом создается файл SO и некоторые другие артефакты.
4.Создайте файл setup.py со следующим содержимым
import setuptools
setuptools.setup(
name="py_metricsql",
packages=setuptools.find_packages(include=["py_metricsql"]),
py_modules = ["py_metricsql.metricsql"],
package_data={"py_metricsql": ["*.so"]},
include_package_data=True,
)
Файл setup.py используется для сборки и установки пакета Python. Он содержит шаблонный код для включения файла SO, созданного на предыдущем этапе.
5.Создайте устанавливаемый .whl файл с помощью setup.py
python3 setup.py bdist_wheel
В результате создается файл .whl в каталоге под названием dist
6.Pip установите файл .whl
wheel_file=$(ls dist/*.whl | head -n1); pip3 install $wheel_file
Теперь версия Python для metricsQL должна быть установлена в вашем окружении. Вы можете убедиться в этом, выполнив следующий фрагмент кода в оболочке Python:
from py_metricsql import metricsql
query = "sum(increase(request_count))"
metricsql.Parse(query)
Если он сработал, то должен вывести разобранный объект запроса.
Вот так! 🎉
Пакет py_metricsql будет обладать всеми функциональными возможностями оригинального пакета Go metricsql!
💡Gopy позаботится о таких вещах, как преобразование всех типов go в типы Python, обработка ошибок и т.д. Это очень экономит время!
Стоит отметить, что обработка ошибок происходит “по-питоновски”. Там, где Go-версия кода возвращает err при каждом вызове функции, Python-версия вызывает исключение:
О чем следует помнить
Хотя использование пакета Go в Python может предоставить мощные возможности, оно также может внести некоторую дополнительную сложность и накладные расходы.
Совместимость: Пакеты Go обычно компилируются в машинный код, что означает, что они должны быть скомпилированы отдельно для каждой операционной системы и архитектуры, на которой они будут использоваться. Это может привести к проблемам совместимости, если скомпилированный двоичный файл не совместим с целевой системой. Если вы поставляете его для внешнего использования, убедитесь, что у вас есть отдельные сборки для всех ОС/архитектур, которые вы хотите поддерживать.
Тестирование: Тестирование проекта Python, использующего пакет Go, может потребовать дополнительных шагов по установке и настройке. Помимо тестирования кода Python, может потребоваться тестирование взаимодействия между кодом Python и пакетом Go.
Использование пакета Go в Python может также привести к возникновению других потенциальных проблем, связанных с производительностью, накладными расходами на разработку и отладку. Поэтому важно тщательно оценить, перевешивают ли преимущества использования пакета Go в вашем проекте Python потенциальные затраты и проблемы.