Python wrapper for SnapAV Binary MoIP control (TCP) and configuration (REST) APIs
Project description
binary-moip
Python wrapper for the SnapAV Binary MoIP controller APIs:
- Control API — TCP port 23, ASCII command protocol (v1.9 spec)
- Configuration API — HTTPS REST + WebSocket events (v1.3.0 spec)
Firmware compatibility
| API | Typical firmware | Notes |
|---|---|---|
| TCP control (port 23) | ≤ 3.x | Legacy integration protocol |
| REST configuration | ≥ 4.x | JWT auth, full device management |
Many current deployments use REST only. Both clients are included for backward compatibility.
Installation
pip install binary-moip
Development install:
git clone https://github.com/binary-moip/binary-moip
cd binary-moip
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Command-line interface
After installation, the binary-moip command is available on your PATH (also runnable as python -m binary_moip.cli).
Connection options
Global flags apply to all subcommands:
| Flag | Environment variable | Description |
|---|---|---|
--host |
MOIP_HOST |
Controller hostname or IP |
--base-url |
MOIP_BASE_URL |
REST base URL (default: https://{host}) |
--user |
MOIP_USER |
Username (optional for control commands) |
--password |
MOIP_PASS |
Password (prompted if unset for config commands) |
--port |
— | TCP control port (default: 23) |
--no-verify-ssl |
— | Disable SSL verification for REST |
--pretty |
— | Pretty-print JSON output |
Security notes
- Prefer the
MOIP_PASSenvironment variable or the interactive prompt over--password. Passing a password as a flag exposes it to other users via the process list; the CLI prints a warning when you do.--no-verify-ssldisables TLS verification and should only be used on a trusted LAN with self-signed appliance certificates. Combined with untrusted networks it enables MITM attacks.config requestis authenticated admin access to the controller. Paths must be relative (e.g./api/v1/moip/unit); absolute URLs are rejected so the bearer token cannot be sent to another host.config watch --rawconnects only to the controller host by default. Pass--allow-alternate-hostto trust a different host reported by the API.
TCP control examples
The control commands use the TCP control connection (port 23). Authentication is
optional and auto-detected: if the controller presents a login prompt the supplied
--user/--password are used, otherwise you can omit them entirely.
# No credentials needed when the controller does not require authentication
binary-moip --host 192.168.1.10 control devices
binary-moip --host 192.168.1.10 --user admin --password secret control devices
binary-moip --host 192.168.1.10 --user admin --password secret control receivers
binary-moip --host 192.168.1.10 --user admin --password secret control names --rx
binary-moip --host 192.168.1.10 --user admin --password secret control switch 1 2
binary-moip --host 192.168.1.10 --user admin --password secret control scenes
binary-moip --host 192.168.1.10 --user admin --password secret control activate-scene "Good Night"
binary-moip --host 192.168.1.10 --user admin --password secret control raw "?Firmware"
REST configuration examples
# Provide the password via the environment to keep it out of the process list
export MOIP_USER=admin MOIP_PASS=secret
binary-moip --host 192.168.1.10 --no-verify-ssl config units
binary-moip --host 192.168.1.10 --no-verify-ssl config system
binary-moip --host 192.168.1.10 --no-verify-ssl config status
binary-moip --host 192.168.1.10 --no-verify-ssl \
config request GET /api/v1/moip/video_rx/1052
binary-moip --host 192.168.1.10 --no-verify-ssl \
config request PUT /api/v1/moip/video_rx/1052 --body '{"settings":{"name":"TV"}}'
binary-moip --host 192.168.1.10 --no-verify-ssl config watch
The config request subcommand provides access to all REST API endpoints. Use config watch to stream change events (Ctrl+C to stop).
Quick start — TCP control
Switch receiver 2 to transmitter 1:
from binary_moip import ControlClient
with ControlClient("192.168.1.10", username="admin", password="secret") as client:
print(client.get_devices()) # DeviceCounts(tx=2, rx=5)
print(client.get_receivers()) # current routing
client.switch(tx=1, rx=2) # !Switch=1,2
Async:
from binary_moip import AsyncControlClient
async with AsyncControlClient("192.168.1.10", "admin", "secret") as client:
await client.switch(1, 2)
Authentication is optional and auto-detected. On connect, if the controller presents a login prompt the supplied credentials are used; otherwise the session is treated as ready and commands are sent immediately. Controllers that do not require authentication can be used without credentials:
with ControlClient("192.168.1.10") as client:
client.switch(tx=1, rx=2)
Quick start — REST configuration
List units and read video RX settings:
from binary_moip import ConfigClient
with ConfigClient("https://192.168.1.10", "admin", "secret", verify_ssl=False) as client:
units = client.moip.list_unit()
video_rx = client.moip.get_video_rx_id(1052, id=1052)
Async:
from binary_moip import AsyncConfigClient
async with AsyncConfigClient("https://192.168.1.10", "admin", "secret", verify_ssl=False) as client:
units = await client.moip.list_unit()
Event subscription
Subscribe to configuration changes via WebSocket:
from binary_moip import AsyncConfigClient
async with AsyncConfigClient("https://192.168.1.10", "admin", "secret", verify_ssl=False) as client:
async for event in client.events.subscribe_websocket():
print(event.action, event.path)
API surface
Control client methods
Query: get_firmware, get_devices, get_receivers, get_names, get_scenes, get_audio_volume_level, get_hdmi_audio_mute
Control: switch, set_resolution, set_osd, clear_osd, set_osd_image, set_osd_source, stop_osd, set_cec, send_serial, send_ir, set_audio_volume_level, set_hdmi_audio_mute, activate_scene, reboot, exit_session
Callbacks: on_unsolicited(callback) for ~Serial, ~Receivers, and ~AudioVolumeLevels messages.
REST client namespaces
client.base—/api/v1/base/*(auth, config, LAN, firmware, info)client.moip—/api/v1/moip/*(units, endpoints, video walls, groups)client.events— WebSocket and raw change socket subscriptionsclient.request(method, path, ...)— arbitrary authenticated requests
All 83 REST routes from API v1.3.0 are exposed as methods on client.base and client.moip. Method names follow the pattern list_unit, get_video_rx_id, put_video_rx_id, etc.
Development
# Regenerate OpenAPI spec from HTML docs
python scripts/extract_openapi.py docs/API_v1.3.0.html
# Regenerate route registry
python scripts/generate_routes.py
# Run tests
pytest
# Lint
ruff check src tests
Examples
See examples/ for standalone scripts (or use the CLI equivalents above):
switch_source.py— TCP switching (binary-moip control switch)list_units.py— REST unit listing (binary-moip config units)watch_events.py— WebSocket listener (binary-moip config watch)
License
MIT — see LICENSE.
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 Distribution
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 binary_moip-0.1.0.tar.gz.
File metadata
- Download URL: binary_moip-0.1.0.tar.gz
- Upload date:
- Size: 39.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1651486a1cfc15af0f32f85317312e68f02073d7f9482d8d46f53c2515ea9091
|
|
| MD5 |
1ad6a2466dddf98172e10e117a75b406
|
|
| BLAKE2b-256 |
85a1040099c2ab3622b45fda005f1fc3113ee48d3b2964a64fa203c6a829a1bf
|
File details
Details for the file binary_moip-0.1.0-py3-none-any.whl.
File metadata
- Download URL: binary_moip-0.1.0-py3-none-any.whl
- Upload date:
- Size: 65.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9f33660a3f52a41661885a348bcce8d277a2e3f3824b9de0f22b51230309003
|
|
| MD5 |
202e2bdf3bb4db492b0e615c4ff8b9a0
|
|
| BLAKE2b-256 |
62b4316c5b8762348f5773444ddd9f60fce620fc5681538a861fbdbfde3855ea
|