tango-frame
tango-frame は、通常の Python 機器制御クラスを TANGO Device Server として自動公開し、それに対応する Python
クライアントを構成するためのフレームワークである。
機器制御クラス自身は PyTango を import する必要がなく、tango.server.Device を継承する必要もない。公開メソッドを TANGO
command、Python の property を TANGO attribute として対応付ける。
基本思想
機器実装と通信層を分離する。
通常の Python 機器制御クラス
|
+---- tango-frame ----> TANGO Device Server
| method -> command
| property -> attribute
|
+---- tango-frame ----> Python client wrapper
|
+---- TANGO DeviceProxy
tango-frame は TANGO の上に別の RPC プロトコルを構築するものではない。TANGO 標準の command / attribute を自動生成し、クライアント側も
DeviceProxy を用いてそれらを呼び出す。
主な機能
- 通常の Python class を機器 API の定義として利用する。
- public method を同名の TANGO command として公開する。
@propertyを TANGO attribute として公開する。- setter を持つ property は read/write attribute とする。
- TANGO で直接表現できる scalar / homogeneous array は native TANGO 型を優先する。
- 複数の異種引数など、TANGO command の1入力で直接表現できない呼び出しだけを1個の JSON string に変換する。
- native TANGO 型で表現できない複雑な戻り値は JSON string に変換する。
- クライアント側は内部で
tango.DeviceProxyを使いながら、元の機器クラスに近い Python method / property API を提供する。 - 機器固有の client-side 処理は自動 remote dispatch を override できる。
構成
src/
└── tango_frame/
├── __init__.py
├── auto_dispatch.py
├── client.py
├── codec.py
├── introspection.py
├── server.py
└── type_mapping.py
example/
└── device_server/
├── src/
│ └── device/
│ ├── device_class.py
│ └── server_tango/
│ ├── tango_ds.py
│ └── device_client.py
└── example/
├── server_start.py
└── client.py
src/tango_frame/ は再利用可能な framework であり、具体的な機器クラスを含まない。
example/device_server/src/device/ は具体的な機器モジュールの例である。device_class.py は TANGO 非依存で、
server_tango/ がその機器に対する TANGO adapter 層になる。
インストール
pip install .
重要:Python / TANGO バージョンへの強い依存性があります。 このフレームワークは汎用的な Python RPC フレームワークではなく、PyTango とそのネイティブライブラリに依存します。Python のバージョン、OS、CPU アーキテクチャ、TANGO ランタイムの組合せによってはインストール・実行できません。既存装置の Python 環境を変更できない場合など、利用できない場面が多数あります。
パッケージ・ランタイム要件(v0.1.4)
| 対象 | 要件・制約 |
|---|---|
| tango-frame | 配布メタデータ上は Python >=3.9。Python 3.7/3.8 では PyTango 10 を使用できません。 |
| PyTango | pytango>=10。10.0.x は Python >=3.9、10.1系および10.3系は Python >=3.10。新しい PyTango の導入には、対応する Python が必要です。 |
| xlogger-py | xlogger-py。PyPI 公開版 0.3.1 の要求は Python >=3.7。 |
| setuptools | ビルド時に setuptools>=61。実行時依存ではありません。 |
| cppTango | PyTango 10.0.x は cppTango >=10.0.0 を要求。PyTango の系列によって必要な cppTango が異なります。 |
| ネイティブ依存 | cppTango が依存する omniORB4 / libzmq 等。PyTango の wheel 提供状況、OS、アーキテクチャ、システムライブラリの制約があります。 |
注意: requires-python >=3.9 はすべての Python 3.9 以降で動作を保証する意味ではありません。例えば Python 3.9 では
PyTango 10.0.x 系の選択が必要で、10.3系は使用できません。Python 3.7 を想定して記述された機器クラスや型注釈があっても、フレームワーク全体が
Python 3.7 で動くことを意味しません。依存関係が解決しても、対象機器・TANGO 環境での動作検証が別途必要です。
公式情報: PyTango 10.0.0、PyTango 10.3.1、xlogger-py 0.3.1。
機器制御クラス
機器制御クラスは通常の Python class のままでよい。
from typing import List
class DeviceClass(object):
def __init__(self) -> None:
self._position = 0.0
def add(self, value: float) -> float:
self._position += value
return self._position
def move(
self,
position: float,
speed: float = 1.0,
wait: bool = True,
) -> bool:
self._position = position
return wait
def get_samples(self) -> List[float]:
return [1.0, 2.0, 3.0]
@property
def position(self) -> float:
return self._position
@position.setter
def position(self, value: float) -> None:
self._position = value
このクラスは TANGO を使わず、通常の Python object として直接実行することもできる。
TANGO Device Server
機器固有の TANGO server class では、AutoDispatchDevice に機器クラスを指定する。
from tango_frame import AutoDispatchDevice
from device.device_class import DeviceClass
class TangoDevice(AutoDispatchDevice):
device_class = DeviceClass
上の例は概ね次の TANGO API に変換される。
add(value: float) -> float
TANGO command: float -> float
move(position: float, speed: float, wait: bool) -> bool
TANGO command: JSON string -> bool
get_samples() -> List[float]
TANGO command: void -> homogeneous float array
position: float
TANGO read/write attribute
サーバー側で実行すべきでないメソッドは、機器固有の server class から除外できる。
class TangoDevice(AutoDispatchDevice):
device_class = DeviceClass
excluded_commands = {"save"}
Device Server の起動自体は通常の PyTango server runtime を使用する。example の -nodb は TANGO database
を使わずローカル試験するためだけの指定であり、framework の前提ではない。
クライアント
同じ機器クラスを AutoDispatchClient に指定する。
from tango_frame import AutoDispatchClient
from device.device_class import DeviceClass
class DeviceClient(AutoDispatchClient):
device_class = DeviceClass
内部通信には TANGO DeviceProxy を使用するが、利用側では Python の method / property として扱う。
device = DeviceClient(
"tango://127.0.0.1:10000/test/tango/device#dbase=no"
)
print(device.position)
print(device.add(2.5))
device.position = 20.0
機器固有の client-side 処理は通常の継承で override する。たとえば save(path) は Device Server 側ではなく client machine
に保存すべきなので、次のように実装できる。
from pathlib import Path
class DeviceClient(AutoDispatchClient):
device_class = DeviceClass
def save(self, path: str) -> str:
data = self.get_data()
Path(path).write_bytes(data)
return path
明示的に実装した client method は自動 remote dispatch より優先される。
型変換
原則として native TANGO 型を使用する。
| Python API | TANGO 上の表現 |
|---|---|
bool |
native boolean |
int |
native integer |
float |
native double |
str |
native string |
homogeneous List[T] |
native TANGO array / spectrum |
| 引数なし / 戻り値なし | void |
| 複数または異種の引数 | 1個の JSON string input |
| native 型にできない複雑な戻り値 | JSON string |
したがって JSON は通常の通信形式ではなく、TANGO の command model に直接対応できない Python 呼び出しを扱うための fallback である。
ドキュメント
Sphinx/MyST のドキュメントは docs/ 以下に置く。
cd docs
./build.sh
バージョン
現在のバージョン: 0.1.4
変更内容は CHANGELOG.md を参照。
Metadata
Release files for tango-frame 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tango_frame-0.1.4.tar.gz | 19.6 kB | With provenance | Details for tango_frame-0.1.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| tango_frame-0.1.4-py3-none-any.whl | Python 3 | none | any | Details for tango_frame-0.1.4-py3-none-any.whl |
Total release size: 37.9 kB
Release files / tango_frame-0.1.4.tar.gz
| Download URL | tango_frame-0.1.4.tar.gz |
|---|---|
| Size | 19.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57f51b9833bbcf9bd2f66a9af407d20378756037cd80bfdf5db3bdb68ceed323
|
|
BLAKE2b-256 checksum How to use checksums |
1e300e3597b54a157a21062a81294d594831e1ae9605aa11443b08eed4a9e5b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / tango_frame-0.1.4-py3-none-any.whl
| Download URL | tango_frame-0.1.4-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6f790989dfe99167515c9cdfd3aa008fe78dbb998d3af72a26e353291c08e69
|
|
BLAKE2b-256 checksum How to use checksums |
93ea94d32fcfedf0bb65033113bfe3f78cf880a5110e17adfd8b3bb3042b953c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logSecurity for tango-frame 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for tango_frame-0.1.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.