Skip to main content

motorcortex-python

pipeline status coverage report PyPI version Python versions License: MIT

Python bindings for the Motorcortex real-time control engine. Connect to a Motorcortex server, read and write parameters, and stream live telemetry over a single TLS-secured websocket.

Installation

pip install motorcortex-python

Requires Python ≥ 3.10. Runtime dependencies (pynng, protobuf) are installed automatically.

Quick start

Recommended — Session context manager (close is automatic, even on exceptions):

import motorcortex

with motorcortex.Session(
    "wss://192.168.2.100",
    certificate="mcx.cert.crt",
    login="admin", password="admin",
    timeout_ms=1000,
) as s:
    # Read a single parameter
    reply = s.req.getParameter("root/Control/dummyDouble").get()
    print(reply.value)

    # Write a parameter
    s.req.setParameter("root/Control/dummyDouble", 3.14).get()

    # Subscribe to a streamed update (every 10th cycle)
    subscription = s.sub.subscribe(
        ["root/Control/dummyDouble"], "myGroup", frq_divider=10,
    )
    subscription.get()
    subscription.notify(lambda result: print(result[0].value))

Explicit-objects form — the original API, still supported:

types = motorcortex.MessageTypes()
tree = motorcortex.ParameterTree()

req, sub = motorcortex.connect(
    "wss://192.168.2.100", types, tree,
    certificate="mcx.cert.crt",
    login="admin", password="admin",
)
try:
    reply = req.getParameter("root/Control/dummyDouble").get()
    print(reply.value)
finally:
    sub.close()
    req.close()

The URL grammar accepts IPv4, hostnames, and IPv6 literals both with and without explicit ports — e.g. wss://host, wss://host:5568:5567, wss://[::1], wss://[fe80::1]:5568:5567.

Unsubscribing and closing

  • sub.unsubscribe(subscription) is the precise control: it removes one group from the server and stops its updates. Use it whenever your application is done with a specific group but keeps running.
  • sub.close() ends the subscribe connection for good and best-effort-removes any groups you didn't unsubscribe (so a churned Subscribe doesn't leave stale groups loading the server). close() is terminal — a closed Subscribe cannot be reconnected; create a new one (or a new Session) instead. Calling connect() on a closed Subscribe resolves to False, it never raises.

If the subscribe connection drops, the library silently redials in the background and fires your state_update callback with CONNECTION_LOST / CONNECTION_OK. After a reconnect, call sub.resubscribe() to restore your groups — motorcortex.connect()'s default reconnect handler already does this for you.

Documentation

  • API reference — docs/_index.md — flat, method-by-method reference for every public class and function. Regenerated from the docstrings via pydoc-markdown.
  • ARCHITECTURE.md — internals tour: module layout, connection lifecycle, subscribe frame format, parameter-tree cache, threading model, error contract, type conventions.
  • examples/README.md — runnable scripts (quickstart.py, error_handling.py) that demonstrate the canonical usage patterns.
  • CHANGELOG.md — version history.

Repository layout

motorcortex/            Python package
test/
  unit/                 Offline unit tests (no server)
  integration/          Live tests against the vendored test_server
  server/               Vendored C++ test_server (CMake project)
docs/                   pydoc-markdown + stub generation scripts
benchmark/              Throughput scripts (not part of the test suite)
sandbox/                Ad-hoc repro scripts

Testing

Unit tests run offline and require only the package itself:

pip install -e .
pip install "coverage[toml]>=7.4"
python -m unittest discover -s test/unit -t .

Integration tests spawn the vendored test_server. Build it once, then run the suite:

cmake -S test/server -B test/server/build -DCMAKE_BUILD_TYPE=Release
cmake --build test/server/build

python -m unittest discover -s test/integration -t .

Coverage (line + branch). pyproject.toml sets parallel = true, so each coverage run writes a per-process data shard; use coverage combine to merge them before coverage report:

coverage erase
coverage run -m unittest discover -s test/unit -t .
coverage run -m unittest discover -s test/integration -t .
coverage combine
coverage report

See test/README.md for the full testing walkthrough.

Regenerating the API reference

docs/_index.md is committed and should be refreshed before each release so the rendered reference matches the code at the tag. The regen is two commands — pydoc-markdown first, then format_api.sh to wrap >>> examples as fenced Python blocks and prepend the front matter:

pip install pydoc-markdown
cd docs
pydoc-markdown pydoc-markdown.yml > _index.md
./format_api.sh

The hook-based one-shot version was dropped — it races with the shell redirect and silently loses output. See docs/readme.md and the comment in docs/pydoc-markdown.yml for the full rationale.

Release process

See PIPHOWTO.md for PyPI release steps and CHANGELOG.md for version history.

License

MIT — see LICENSE.

Download files

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

Source Distribution

motorcortex_python-1.2.0.tar.gz (71.3 kB view details)

Uploaded Source

Built Distribution

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

motorcortex_python-1.2.0-py3-none-any.whl (78.5 kB view details)

Uploaded Python 3

File details

Details for the file motorcortex_python-1.2.0.tar.gz.

File metadata

  • Download URL: motorcortex_python-1.2.0.tar.gz
  • Upload date:
  • Size: 71.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for motorcortex_python-1.2.0.tar.gz
Algorithm Hash digest
SHA256 97124b2776ebc2b129f818ea032b91118a0a78ec956a2e961e0513e8b2404890
MD5 b7e834438c33aa27e578ae47a55ae585
BLAKE2b-256 b1eb8de9a212acb1b5f22807df11eaf2db4852aa5dc4127158957a5f47215fc8

See more details on using hashes here.

File details

Details for the file motorcortex_python-1.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for motorcortex_python-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd15c344f6b90014db0ba4eec57c1b1427194ebdfda1e3cf3b7f3391905b9d35
MD5 b57b6e29a704c9216fbc32499c1f2c8f
BLAKE2b-256 a927173b62a593beb19cecac2809db26ba94b701901de27387bbf8631ba984b4

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.25.5

1 file

0.25.4

1 file

0.25.1

1 file

0.25.0

1 file

0.24.2

1 file

0.24.1

1 file

0.23.3

1 file

0.23.2

1 file

0.23.0

1 file

0.22.9

1 file

0.22.7

1 file

0.22.6

1 file

0.22.5

1 file

0.22.4

1 file

0.22.3

1 file

0.22.2

1 file

0.22.1

1 file

0.22.0

1 file

0.21.7

1 file

0.21.6

1 file

0.21.5

1 file

0.21.0

1 file

0.20.18

1 file

0.20.17

1 file

0.20.16

1 file

0.20.15

1 file

0.20.14

1 file

0.20.13

1 file

0.20.12

1 file

0.20.11

1 file

0.20.10

1 file

0.20.9

1 file

0.20.8

1 file

0.20.7

1 file

0.20.6

1 file

0.20.5

1 file

0.20.4

1 file

0.20.1

1 file

0.20.0

1 file

0.10.2

1 file

0.10.1

1 file

0.10.0

1 file

0.9.16

1 file

0.9.15

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page