motorcortex-python
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 churnedSubscribedoesn't leave stale groups loading the server).close()is terminal — a closedSubscribecannot be reconnected; create a new one (or a newSession) instead. Callingconnect()on a closedSubscriberesolves toFalse, 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 viapydoc-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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| motorcortex_python-1.2.1.tar.gz | 73.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| motorcortex_python-1.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 154.0 kB
Release files / motorcortex_python-1.2.1.tar.gz
| Download URL | motorcortex_python-1.2.1.tar.gz |
|---|---|
| Size | 73.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
587452772b831ac2b784329fa77749b0660208c5f5c1694932b8a766770f4023
|
|
BLAKE2b-256 checksum How to use checksums |
6be1b8095bd8a27dd832b6ec2ca7d62e9d007d33fdfc4ad37bcc9aa57336dbdd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / motorcortex_python-1.2.1-py3-none-any.whl
| Download URL | motorcortex_python-1.2.1-py3-none-any.whl |
|---|---|
| Size | 80.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
03b3c62fbc9c20083df3b4823792495b29919cca9d38e18153d0ed603073b7de
|
|
BLAKE2b-256 checksum How to use checksums |
1ad69adfc6f11528a8c488e32006822887ccd86b6a394a6ac6544c39357c8fbd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for motorcortex-python 1.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.