Создаем свой компонент на Python

Зачем это нужно?

Когда я начал учиться проектировать информационные системы на базе микро сервисов, то обнаружил, что часто требуется при построении архитектуры использовать в разных микро сервисах в рамках одного большого проекта одни и те же классы. Например, класс для работы с нашим хранилищем Minio s3, или класс для работы с RabbitMQ, класс для работы с шиной данных и другие классы.

После того, как я некоторое время потаскал эти файлы с классами из проекта в проект, смог убедиться в том, что это очень неудобно и быстро надоедает. Идеальным вариантом было бы иметь компонент, который инсталлируется в Docker во время установки зависимости из файла requirements.txt.

В PHP для таких вещей удобно использовать композер. А как именно упаковать компонент в транспортный пакет для Python, мне как раз и предстояло разобраться.

В целом, то, что я описал тут, можно найти на https://packaging.python.org/en/latest/tutorials/packaging-projects/#uploading-your-project-to-pypi

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

Подготовка компонента для упаковки

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

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

Для начала, я создаю папку rabbit_hadler_kvg и в ней создаю 2 папки с двумя файлами в каждой:

rabbit_handler_kvg/rabbit_handler_kvg.py
rabbit_handler_kvg/__init__.py
README.md
setup.py
Файлы в папке rabbit_hadler_kvg

Теперь по каждому из этих компонентов. Первое rabbit_handler_kvg/rabbit_handler_kvg.py — это сам класс, который мы хотим упаковать.

Файл rabbit_handler_kvg/init.py — в нем мы подключаем различные классы при инициализации.

from rabbit_handler_kvg.rabbit_handler_kvg import RabbitQueueInformer,RabbitQueueTaskSender,RabbitQueueConsumer
__init__.py

Второе, setup.py — файлик с данными о пакете. В нем содержится информация о пакете, а также массив install_requires с зависимостями, необходимыми для установки пакета.

В моем случае, класс выглядит таким образом:

from setuptools import setup

setup(
name='rabbit_handler_kvg',
version='1.0.0',
description='A handler for rabbitMQ',
author='Vyacheslav Kosarev',
author_email='vyach.kosarev@gmail.com',
packages=['rabbit_handler_kvg'],
install_requires=['pika','python-dotenv','requests']
)
setup.py

В файле README.md прописываете инструкции о том, как использовать ваш пакет. Даже если делаете компонент чисто для себя, обязательно напишите инструкцию, как его использовать, т.к. даже через 3 месяца можете не вспомнить сразу и придется опять читать свой код, чтобы вспомнить, как его подключить.

#rabbit_handler_kvg

Содержит три класса:

RabbitQueueInformer - класс для получения информации об конкретной очереди в системе rabbitMQ
RabbitQueueTaskSender(RabbitQueueInformer) - класс для отправки сообщений в очередь
RabbitQueueConsumer(RabbitQueueInformer) - класс для прослушивания очереди

Подключение
Для подключения требуется передать файл с конфигурационными данными для подключения к хосту rabbitMQ

def __init__(self, config):
self.rabbit_host = config['RABBIT_HOST']
self.rabbit_user = config['RABBIT_USER']
self.rabbit_pass = config['RABBIT_PASS']

В файле использования подключить класс: <br>
from rabbit_handler_kvg import rabbit_handler_kvg

Запуск скрипта:

Прием сообщений
rb = rabbit_handler_kvg.RabbitQueueConsumer("queue_name", config)

Отправка сообщений
rb = rabbit_handler_kvg.RabbitQueueTaskSender("queue_name", config)

rb.rest_queue_list()

json = '{"ffdf":"Приsadfdasвет"}'
rb.send_to_queue(json)
README.md

Итак, теперь у нас все готово, чтобы создать дистрибутив. Давайте создадим его!

Вводим в терминале команду

python setup.py sdist bdist_wheel

Эта команда создаст папку dist с дистрибутивом. В моем случае, это 2 файла:

rabbit_handler_kvg-1.0.0.tar.gz
rabbit_handler_kvg-1.0.0-py3-none-any.whl
Содержимое папки dist

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

pip install rabbit_handler_kvg-1.0.0-py3-none-any.whl

Это будет работать. Однако, наша задача не просто установить класс, который будет работать, а класс, который можно будет подключить в любом проекте, установив одной командой и без необходимости таскать эти файлы из места в место.

Для того, чтобы загрузить это в сервис pypi.org нужно при включенной авторизации по API токену создать файлик .pypirc

[pypi]
username = __token__
password = [Ваш токен]
.pypirc

Если все настроено правильно и файл располагается по пути

В операционных системах Linux и macOS это обычно /home/ваше_имя_пользователя/.pypirc, а в Windows - C:\Users\ваше_имя_пользователя\.pypirc.

То команда

twine upload dist/*

загрузит ваш компонент на сервер.

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

pip install rabbit-handler-kvg

Класс создан для расширения, т.е. в нем есть все необходимое для расширения в случае необходимости дописать свои необходимые методы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *