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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a68134092c25bb42b54a1ce77bb922b2391834e51b0ed98242d355ee0c3e9aff
|
|
| MD5 |
50b8fe832af30bfb0bd94b08a34c44fc
|
|
| BLAKE2b-256 |
b793bfd5e9a1fc35424059de6b412bc79619c0477c5cccc85484cf9edfdb18b4
|
Provenance
The following attestation bundles were made for sismatic-0.2.18.tar.gz:
Publisher:
pipeline.yml on metzenseifner/sismatic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sismatic-0.2.18.tar.gz -
Subject digest:
a68134092c25bb42b54a1ce77bb922b2391834e51b0ed98242d355ee0c3e9aff - Sigstore transparency entry: 2194976766
- Sigstore integration time:
-
Permalink:
metzenseifner/sismatic@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Branch / Tag:
refs/tags/v0.2.18 - Owner: https://github.com/metzenseifner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pipeline.yml@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Trigger Event:
push
-
Statement type:
File details
Details for the file sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
900d6f1f1c29c624487495c0d79cb56bd743a1097127065bfe385291a9682675
|
|
| MD5 |
4cb77e5550f2f1f3f73223f69904ca27
|
|
| BLAKE2b-256 |
6b5b372df5c0a3b8f1d6de2f41102330c8433ef86af671faba1a396755d3d5d9
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sismatic-0.2.18-cp39-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
900d6f1f1c29c624487495c0d79cb56bd743a1097127065bfe385291a9682675 - Sigstore transparency entry: 2194976774
- Sigstore integration time:
-
Permalink:
metzenseifner/sismatic@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Branch / Tag:
refs/tags/v0.2.18 - Owner: https://github.com/metzenseifner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pipeline.yml@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Trigger Event:
push
-
Statement type:
File details
Details for the file sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1056bf23c0f276960ffced1c48cbbabaa7c45a5cfcc91fdcdbbe84918cd1237b
|
|
| MD5 |
d60220f0407a8c4e83bcdeffc35ab77d
|
|
| BLAKE2b-256 |
4c58f6759ab383660799641c9650c9c305701477844769fe375b65d1dd69598a
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sismatic-0.2.18-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
1056bf23c0f276960ffced1c48cbbabaa7c45a5cfcc91fdcdbbe84918cd1237b - Sigstore transparency entry: 2194976782
- Sigstore integration time:
-
Permalink:
metzenseifner/sismatic@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Branch / Tag:
refs/tags/v0.2.18 - Owner: https://github.com/metzenseifner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pipeline.yml@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Trigger Event:
push
-
Statement type:
File details
Details for the file sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.7 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
820c38c3713845f3d6bb07ebc95c2a11aca494687be4c83678c9b6b1da7f40f8
|
|
| MD5 |
368971878b5056baa88acf50a5b4b03c
|
|
| BLAKE2b-256 |
5f0876e9b515c740c58a0e951a48e7310a1406014ba7e1e73c0655a8849679ba
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sismatic-0.2.18-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
820c38c3713845f3d6bb07ebc95c2a11aca494687be4c83678c9b6b1da7f40f8 - Sigstore transparency entry: 2194976770
- Sigstore integration time:
-
Permalink:
metzenseifner/sismatic@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Branch / Tag:
refs/tags/v0.2.18 - Owner: https://github.com/metzenseifner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pipeline.yml@ad853aff60c3b379d3eb06aeeeda34afb5d0cffc -
Trigger Event:
push
-
Statement type: