English

プラグイン開発ガイド(message type/ Python)

1. はじめに

SINETStream では設定ファイルあるいはコンストラクタのパラメータで指定するvalue_typeの値に応じて、 メッセージのシリアライズ、デシリアライズを行います。

SINETStream v1.1 以降では以下の value_type をサポートしています。

byte_array, textはSINETStream本体に組み込みの value_type です。 imageは追加プラグインとして提供しているvalue_typeです。

新たなプラグインを実装することで、上記に示したvalue_type以外のタイプをSINETStreamのメッセージとして扱えるようになります。

1.1 対象者

このドキュメントが対象としている読者を以下に示します。

1.2 前提知識

このドキュメントの説明は、以下の知識を有している読者を前提としています。

2. プラグインの実装方法

2.1 概要

SINETStreamのプラグインを作成するためには以下の作業が必要となります。

それぞれの作業項目の詳細について以下に記します。

2.2 プラグインに定められているプロパティを実装したクラスの作成

value_typeのプラグインではメッセージのタイプに応じたシリアライザ、デシリアライザをプロパティとして提供する必要があります。 具体的には以下のプロパティの定義が必要となります。

プラグインが上記のプロパティを実装することを確認するために、 抽象基底クラス sinetstream.spi.PluginValueTypeを利用することができます。 PluginValueTypeでは上記のプロパティが抽象プロパティとして定義されています。

2.3 パッケージメタデータの作成

setuptoolsのエントリポイントにクラスを登録することで、SINETStreamがプラグインを見つけることができるようになります。 これは登録されたエントリポイントをsetuptoolsが検出する機能を利用して実現しています。 setuptoolsはPythonの配布パッケージのビルドなどを行うためのツールです。

登録されているエントリポイントからSINETStreamで必要となるクラスを探し出すことができるようにするためには、 エントリポイントのグループと名前を適切に設定する必要があります。 value_typeプラグインではsinetstream.value_typeをグループに指定します。 また名前には value_typeとして追加するタイプ名を指定します。

例えばvalue_typeimageを追加するプラグインの場合setup.cfg に以下の記述を行います。

[options.entry_points]
sinetstream.value_type =
    image = sinetstreamplugin.valuetype.image:ImageValueType

エントリポイントの詳細については setuptools documentation - Entry Points を参照してください。

3. プラグインの実装例

プラグイン実装の具体的な手順を示すために実装例を示します。

ここでは dict型のオブジェクトをSINETStreamのメッセージとして扱えるようにするためのvalue_typeプラグインを実装します。

3.1 ファイル構成

以下のファイルを作成します。

3.2 プラグイン実装

プラグインの実装を行うモジュールファイルmap_yaml.pyについて説明します。

まずクラス定義を行います。

class MapYamlValueType(PluginValueType):

ここでは抽象基底クラスPluginValueTypeを継承したクラスを定義します。 プラグインクラスの実装においてPluginValueTypeを継承することは必須ではありません。 しかし開発環境によっては抽象基底クラスを継承することにより、 プラグイン実装に必要となるメソッドに関する情報などの支援を受けられる場合があります。

次にシリアライザ、デシリアライザの処理を実装するメソッドを定義します。

    def _map_to_bytes(self, params):
        return safe_dump(params, encoding='utf-8')

    def _map_from_bytes(self, data):
        return safe_load(data)

ここでは dict型のオブジェクトを Yamlのバイト列に変換するシリアライザと、 その逆向きの処理を行うデシリアライザを定義しています。

次にプラグインで実装する必要のあるプロパティを定義します。

    @property
    def serializer(self):
        return self._map_to_bytes

    @property
    def deserializer(self):
        return self._map_from_bytes

先ほど定義したシリアライザ_map_to_bytes、デシリアライザ_map_from_bytesを返すプロパティを定義しています。

3.3 パッケージング

3.3.1 setup.py, setup.cfgの作成

パッケージングを行う際のコマンドラインインタフェースとなる setup.py とその設定ファイル setup.cfg を作成します。

まず setup.py を作成します。設定については全てsetup.cfgで行うので setup.pyは必要最小限なものとします。

from setuptools import setup
setup()

次に setup.cfg を作成します。

[metadata]
name = sinetstream-type-map-yaml
version = 1.0.0

[options]
package_dir=
    =src
packages = find_namespace:
zip_safe = False
namespace_packages =
  ssplugin
install_requires =
  sinetstream>=1.1.0
  pyyaml
python_requires = >= 3.6

[options.packages.find]
where = src

[options.entry_points]
sinetstream.value_type =
    map_yaml = ssplugin.map_yaml:MapYamlValueType

プラグインに直接関わる設定は options.entry_pointsセクションです。 sinetstream.value_typevalue_typeプラグインに対応するグループになります。 グループに対して (value_typeのタイプ名)=(パッケージ名:クラス名) を指定しています。

3.3.2 パッケージの作成

wheelパッケージを作成します。

$ python setup.py bdist_wheel
running bdist_wheel
running build
running build_py
(中略)
$ ls dist/
dist/sinetstream_type_map_yaml-1.0.0-py3-none-any.whl

3.4 利用例

作成したプラグインを利用して dict型オブジェクトを送信する例を以下に示します。

msg = {
    'message': 'message 001',
    'value': 17,
}

with MessageWriter(service='service-1', value_type='map_yaml') as writer:
    writer.publish(msg)

MessageWriterのコンストラクタのパラメータvalue_typeの値に、 新たに作成したvalue_typeプラグインのタイプ名map_yamlを指定しています。 そのため、writer.publish()の引数に直接dict型変数を渡すことができます。

3.5 ソースコード

ここまで記した実装例のファイルへのリンクを以下に示します。