Skip to main content

Blocking Python facade for driving Extron SIS devices over SSH

Project description

sismatic

A blocking Python facade for driving Extron devices over SSH using their Simple Instruction Set (SIS). The name is SIS + automatic: it handles the SIS machinery — connection pooling, the SSH handshake, byte-level framing — behind the scenes so you address a pool of devices by id and send plain instructions.

The package is a thin Python layer over a compiled Rust extension (sismatic-core), shipped as an abi3 wheel that covers CPython 3.9+ with a single build.

Install

pip install sismatic

Quickstart

from sismatic import Sis

# No connections are opened here; devices connect lazily on first use.
sis = Sis.from_file("devices.toml")

for device_id in sorted(sis.ids()):
    print(device_id)

sis.query("atrium-101", "firmware")          # read a built-in field
sis.register("atrium-101", "title", "Wk 4")  # write a metadata register
sis.command("atrium-101", "start")           # run a recorder command

Use it as a context manager to tear the session down deterministically:

with Sis.from_file("devices.toml") as sis:
    sis.command("atrium-101", "start")
# every SSH connection is closed on exit

Configuration

from_file

from_file picks the deserializer from the extension (.toml, .json, .yaml/.yml). A config is a defaults table plus a list of devices:

[defaults]
port = 22023
connect_secs = 5
command_secs = 3
eager = true              # open connections up front instead of on first use
sis_keepalive_secs = 120  # probe idle devices so warm connections stay warm

[[device]]
id = "atrium-101"
host = "10.0.0.7"
username = "admin"
password = "extron"

[[device]]
id = "annex-far"
host = "10.0.0.8"
username = "admin"
password = "extron"
connect_secs = 10  # per-device override
command_secs = 8

from_config

Not using a file? Sis.from_config(mapping) takes an already-parsed dict shaped the same way, so you own the parsing. You can have a source config in any format like INI, XML, a database row, or environment variables with any parser that can produce a dictionary in the expected format.

Minimal Example with a configuration literal (no additonal parsing):

from sismatic import Sis
import logging
logging.basicConfig(level=logging.DEBUG)

devices = {
  "defaults": {
    "username": "joe",
    "password": "schmoe",
    "eager": True,
    "sis_keepalive_secs": 120,
    "port": 22023,
  },
  "devices": [
      {"id": "Hall A", "host": "https://10.0.150.1"},
      {"id": "Hall B", "host": "https://10.0.150.2"},
  ],
}
sis = Sis.from_config(devices)
print(sis.ids())

Connections

Connections are lazy by default — the expensive SSH handshake is paid on a device's first instruction. Set eager to pay it up front, and sis_keepalive_secs to send a benign probe on an interval so a device's inactivity timer never lets the connection go cold. See the design note on eager connections and SIS keepalive for the full rationale.

API at a glance

>>> from sismatic import Sis
>>> [m for m in dir(Sis) if not m.startswith('_')]
['close', 'command', 'from_config', 'from_file', 'from_toml', 'ids', 'query', 'register']

The wheel ships a PEP 561 py.typed marker and a type stub, so editors and mypy see full signatures, including the exact accepted instruction names. Full API docs: https://metzenseifner.github.io/sismatic/.

Example: start a recording across a batch of devices

# control_recording.py
# Starts recording and stamps a title across a batch of devices.

from dataclasses import dataclass
from sismatic import Sis

@dataclass(frozen=True)
class RecordingJob:
    """(device_id × title) as a product type. A job is exactly a pairing of
    the two — never one without the other — so the type says that, instead
    of the two strings being threaded separately through every call site as
    two positional arguments that happen to always travel together."""
    device_id: str
    title: str


def run_job(sis: Sis, job: RecordingJob) -> None:
    sis.register(job.device_id, "title", job.title)  # "title" — see Register::Title
    sis.command(job.device_id, "start")              # "start" — see Command::Start


def main() -> None:
    with Sis.from_file("devices.toml") as sis:
        jobs = [
            RecordingJob(device_id="atrium-101", title="Week 4 — Lecture"),
            RecordingJob(device_id="annex-far", title="Week 4 — Overflow Room"),
        ]
        for job in jobs:
            run_job(sis, job)


if __name__ == "__main__":
    main()

License

ECL-2.0. Part of the sismatic workspace.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sismatic-0.2.18.tar.gz (91.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl (2.5 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file sismatic-0.2.18.tar.gz.

File metadata

  • Download URL: sismatic-0.2.18.tar.gz
  • Upload date:
  • Size: 91.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sismatic-0.2.18.tar.gz
Algorithm Hash digest
SHA256 a68134092c25bb42b54a1ce77bb922b2391834e51b0ed98242d355ee0c3e9aff
MD5 50b8fe832af30bfb0bd94b08a34c44fc
BLAKE2b-256 b793bfd5e9a1fc35424059de6b412bc79619c0477c5cccc85484cf9edfdb18b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sismatic-0.2.18.tar.gz:

Publisher: pipeline.yml on metzenseifner/sismatic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 900d6f1f1c29c624487495c0d79cb56bd743a1097127065bfe385291a9682675
MD5 4cb77e5550f2f1f3f73223f69904ca27
BLAKE2b-256 6b5b372df5c0a3b8f1d6de2f41102330c8433ef86af671faba1a396755d3d5d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl:

Publisher: pipeline.yml on metzenseifner/sismatic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1056bf23c0f276960ffced1c48cbbabaa7c45a5cfcc91fdcdbbe84918cd1237b
MD5 d60220f0407a8c4e83bcdeffc35ab77d
BLAKE2b-256 4c58f6759ab383660799641c9650c9c305701477844769fe375b65d1dd69598a

See more details on using hashes here.

Provenance

The following attestation bundles were made for sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: pipeline.yml on metzenseifner/sismatic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 820c38c3713845f3d6bb07ebc95c2a11aca494687be4c83678c9b6b1da7f40f8
MD5 368971878b5056baa88acf50a5b4b03c
BLAKE2b-256 5f0876e9b515c740c58a0e951a48e7310a1406014ba7e1e73c0655a8849679ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: pipeline.yml on metzenseifner/sismatic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page