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.

Metadata

Release files for motorcortex-python 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for motorcortex-python 1.2.0
File Size Uploaded
motorcortex_python-1.2.0.tar.gz 71.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for motorcortex-python 1.2.0
File Interpreter ABI Platform
motorcortex_python-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 149.8 kB

Release files / motorcortex_python-1.2.0.tar.gz

Download URL motorcortex_python-1.2.0.tar.gz
Size 71.3 kB
Tags Source
SHA-256 checksum
How to use checksums
97124b2776ebc2b129f818ea032b91118a0a78ec956a2e961e0513e8b2404890
BLAKE2b-256 checksum
How to use checksums
b1eb8de9a212acb1b5f22807df11eaf2db4852aa5dc4127158957a5f47215fc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / motorcortex_python-1.2.0-py3-none-any.whl

Download URL motorcortex_python-1.2.0-py3-none-any.whl
Size 78.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd15c344f6b90014db0ba4eec57c1b1427194ebdfda1e3cf3b7f3391905b9d35
BLAKE2b-256 checksum
How to use checksums
a927173b62a593beb19cecac2809db26ba94b701901de27387bbf8631ba984b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release history Release notifications | RSS feed

1.2.1

2 release files

This release

1.2.0 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.25.5

1 release file

0.25.4

1 release file

0.25.1

1 release file

0.25.0

1 release file

0.24.2

1 release file

0.24.1

1 release file

0.23.3

1 release file

0.23.2

1 release file

0.23.0

1 release file

0.22.9

1 release file

0.22.7

1 release file

0.22.6

1 release file

0.22.5

1 release file

0.22.4

1 release file

0.22.3

1 release file

0.22.2

1 release file

0.22.1

1 release file

0.22.0

1 release file

0.21.7

1 release file

0.21.6

1 release file

0.21.5

1 release file

0.21.0

1 release file

0.20.18

1 release file

0.20.17

1 release file

0.20.14

1 release file

0.20.13

1 release file

0.20.12

1 release file

0.20.11

1 release file

0.20.10

1 release file

0.20.9

1 release file

0.20.8

1 release file

0.20.7

1 release file

0.20.6

1 release file

0.20.5

1 release file

0.20.4

1 release file

0.20.1

1 release file

0.20.0

1 release file

0.10.2

1 release file

0.10.1

1 release file

0.10.0

1 release file

0.9.16

1 release file

0.9.15

1 release 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