motorcortex-python 1.0.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.1
2
+ Name: motorcortex-python
3
+ Version: 1.0.0rc1
4
+ Summary: Python bindings for Motorcortex Engine
5
+ Home-page: https://www.motorcortex.io
6
+ Author: Alexey Zakharov
7
+ Author-email: alexey.zakharov@vectioneer.com
8
+ License: MIT
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: System :: Distributed Computing
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: pynng<2,>=0.9.0
24
+ Requires-Dist: protobuf>=3.20
25
+
26
+ # motorcortex-python
27
+
28
+ [![pipeline status](https://git.vectioneer.com/pub/motorcortex-python/badges/master/pipeline.svg)](https://git.vectioneer.com/pub/motorcortex-python/-/commits/master)
29
+ [![coverage report](https://git.vectioneer.com/pub/motorcortex-python/badges/master/coverage.svg?job=coverage)](https://git.vectioneer.com/pub/motorcortex-python/-/commits/master)
30
+ [![PyPI version](https://img.shields.io/pypi/v/motorcortex-python.svg)](https://pypi.org/project/motorcortex-python/)
31
+ [![Python versions](https://img.shields.io/pypi/pyversions/motorcortex-python.svg)](https://pypi.org/project/motorcortex-python/)
32
+ [![License: MIT](https://img.shields.io/pypi/l/motorcortex-python.svg)](LICENSE)
33
+
34
+ Python bindings for the [Motorcortex](https://www.motorcortex.io) real-time control engine. Connect to a Motorcortex server, read and write parameters, and stream live telemetry over a single TLS-secured websocket.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install motorcortex-python
40
+ ```
41
+
42
+ Requires Python ≥ 3.10. Runtime dependencies (`pynng`, `protobuf`) are installed automatically.
43
+
44
+ ## Quick start
45
+
46
+ Recommended — `Session` context manager (close is automatic, even on exceptions):
47
+
48
+ ```python
49
+ import motorcortex
50
+
51
+ with motorcortex.Session(
52
+ "wss://192.168.2.100",
53
+ certificate="mcx.cert.crt",
54
+ login="admin", password="admin",
55
+ timeout_ms=1000,
56
+ ) as s:
57
+ # Read a single parameter
58
+ reply = s.req.getParameter("root/Control/dummyDouble").get()
59
+ print(reply.value)
60
+
61
+ # Write a parameter
62
+ s.req.setParameter("root/Control/dummyDouble", 3.14).get()
63
+
64
+ # Subscribe to a streamed update (every 10th cycle)
65
+ subscription = s.sub.subscribe(
66
+ ["root/Control/dummyDouble"], "myGroup", frq_divider=10,
67
+ )
68
+ subscription.get()
69
+ subscription.notify(lambda result: print(result[0].value))
70
+ ```
71
+
72
+ Explicit-objects form — the original API, still supported:
73
+
74
+ ```python
75
+ types = motorcortex.MessageTypes()
76
+ tree = motorcortex.ParameterTree()
77
+
78
+ req, sub = motorcortex.connect(
79
+ "wss://192.168.2.100", types, tree,
80
+ certificate="mcx.cert.crt",
81
+ login="admin", password="admin",
82
+ )
83
+ try:
84
+ reply = req.getParameter("root/Control/dummyDouble").get()
85
+ print(reply.value)
86
+ finally:
87
+ sub.close()
88
+ req.close()
89
+ ```
90
+
91
+ 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`.
92
+
93
+ ## Documentation
94
+
95
+ - **[API reference — `docs/_index.md`](docs/_index.md)** — flat, method-by-method reference for every public class and function. Regenerated from the docstrings via `pydoc-markdown`.
96
+ - **[`ARCHITECTURE.md`](ARCHITECTURE.md)** — internals tour: module layout, connection lifecycle, subscribe frame format, parameter-tree cache, threading model, error contract, type conventions.
97
+ - **[`examples/README.md`](examples/README.md)** — runnable scripts (`quickstart.py`, `error_handling.py`) that demonstrate the canonical usage patterns.
98
+ - **[`CHANGELOG.md`](CHANGELOG.md)** — version history.
99
+
100
+ ## Repository layout
101
+
102
+ ```
103
+ motorcortex/ Python package
104
+ test/
105
+ unit/ Offline unit tests (no server)
106
+ integration/ Live tests against the vendored test_server
107
+ server/ Vendored C++ test_server (CMake project)
108
+ docs/ pydoc-markdown + stub generation scripts
109
+ benchmark/ Throughput scripts (not part of the test suite)
110
+ sandbox/ Ad-hoc repro scripts
111
+ ```
112
+
113
+ ## Testing
114
+
115
+ Unit tests run offline and require only the package itself:
116
+
117
+ ```bash
118
+ pip install -e .
119
+ pip install "coverage[toml]>=7.4"
120
+ python -m unittest discover -s test/unit -t .
121
+ ```
122
+
123
+ Integration tests spawn the vendored `test_server`. Build it once, then run the suite:
124
+
125
+ ```bash
126
+ cmake -S test/server -B test/server/build -DCMAKE_BUILD_TYPE=Release
127
+ cmake --build test/server/build
128
+
129
+ python -m unittest discover -s test/integration -t .
130
+ ```
131
+
132
+ Coverage (line + branch). `pyproject.toml` sets `parallel = true`, so each
133
+ `coverage run` writes a per-process data shard; use `coverage combine` to
134
+ merge them before `coverage report`:
135
+
136
+ ```bash
137
+ coverage erase
138
+ coverage run -m unittest discover -s test/unit -t .
139
+ coverage run -m unittest discover -s test/integration -t .
140
+ coverage combine
141
+ coverage report
142
+ ```
143
+
144
+ See [`test/README.md`](test/README.md) for the full testing walkthrough.
145
+
146
+ ## Regenerating the API reference
147
+
148
+ [`docs/_index.md`](docs/_index.md) is committed and should be refreshed
149
+ before each release so the rendered reference matches the code at
150
+ the tag. The regen is two commands — `pydoc-markdown` first, then
151
+ `format_api.sh` to wrap `>>>` examples as fenced Python blocks and
152
+ prepend the front matter:
153
+
154
+ ```bash
155
+ pip install pydoc-markdown
156
+ cd docs
157
+ pydoc-markdown pydoc-markdown.yml > _index.md
158
+ ./format_api.sh
159
+ ```
160
+
161
+ The hook-based one-shot version was dropped — it races with the
162
+ shell redirect and silently loses output. See `docs/readme.md` and
163
+ the comment in `docs/pydoc-markdown.yml` for the full rationale.
164
+
165
+ ## Release process
166
+
167
+ See [`PIPHOWTO.md`](PIPHOWTO.md) for PyPI release steps and [`CHANGELOG.md`](CHANGELOG.md) for version history.
168
+
169
+ ## License
170
+
171
+ MIT — see [`LICENSE`](LICENSE).
@@ -0,0 +1,28 @@
1
+ motorcortex/__init__.py,sha256=wzoArp3S1h7iRcfGnRbvteR5x-HuVMwBwy7JGBnrsKQ,11965
2
+ motorcortex/_connection_state.py,sha256=0jos75PAyMsN3ew6HRoRDbLY-lGCzDit-SiUR7ZvnlA,2203
3
+ motorcortex/_request_builders.py,sha256=bMZAP1ko6jju1wXs5p6TCp4D93wbvSgpKRf3gvW9_Bg,5245
4
+ motorcortex/_request_utils.py,sha256=npW68Mr8YJk6jGek3CDIAZoFGFULQwaIRhlnNW0aDeA,12115
5
+ motorcortex/_subscribe_dispatch.py,sha256=mPXSqo44RgGryLZabj5xmBd7riW154kA8fnCEQ3Mjho,2942
6
+ motorcortex/exceptions.py,sha256=9xFscRC2yEO2AxesxJ15p6DimDVRIdOeCdj4gF0gahs,2239
7
+ motorcortex/init_threads.py,sha256=rT0VRhdwQfI0ziTi_jeEaLxTzCtkgVo71gmQIeQyuv8,3343
8
+ motorcortex/message_types.py,sha256=FA9jcrHS8lf_KxMi4qF5-bTDvZoGRoZ4paPS8oCF35k,15643
9
+ motorcortex/motorcortex_hash.json,sha256=727K4JXwdtqzkIPtlq7ROSVOKLEsy1za3D7IjlLqFpA,3572
10
+ motorcortex/motorcortex_pb2.py,sha256=bMRS3TcCJMbBGYqGKnmTiQZaTmpbiJv0iYU3EF8s29Q,12790
11
+ motorcortex/motorcortex_pb2.pyi,sha256=8mxofEtlFESwybu9eeo_i5iMw35eNqsmr2DjHU9pg1k,70451
12
+ motorcortex/nng_url.py,sha256=LXmeu_Z1Hn0_YkF4QqLN2SiEvG2_AvKlsYK1Cox_1RQ,1386
13
+ motorcortex/parameter_tree.py,sha256=i9nyo40okT8Y8WfPF2M9FZmCo59oXWuu3PXxmfexFtU,2696
14
+ motorcortex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ motorcortex/reply.py,sha256=GMTaDQ_jeu32H5Zl4LA2Smw_PzNuho2cLuzY-1vvJQ0,3889
16
+ motorcortex/request.py,sha256=r16i1CZOl8qVvSrVNqMocdsOQCjiKw21XfKtN6PqMc0,26253
17
+ motorcortex/session.py,sha256=d5V3q5S5cATJ4Dm9W-lZo388o98ccX48B1fAjgQZ-5U,7038
18
+ motorcortex/setup_logger.py,sha256=ynWC2xMPC5lw_ubU1AL7lbuxm4VK2xqkLRNisAv_fZM,195
19
+ motorcortex/state_callback_handler.py,sha256=Vr9XZ5vN7-CKJdvbJlFkenwH6JfhuInkM1RQvRnlhPY,3069
20
+ motorcortex/subscribe.py,sha256=A0lFkkFTqEh8vSdGvr1JBq25gjo-xh4Ai_kcoW4aPIA,15715
21
+ motorcortex/subscription.py,sha256=n_7OKE_u-Sz0T49S54RuYXlJ2uzXPFzxeXIGg91lfLM,15406
22
+ motorcortex/timespec.py,sha256=bZ-CD2EY0ALoWmJyluThxkiqfVCiGZqPPHRlKSvq7Fs,4573
23
+ motorcortex/version.py,sha256=Zf80zUin_WQ77tGbDMBKvURmGcFKDgnESRwu7q6VXQk,25
24
+ motorcortex_python-1.0.0rc1.dist-info/LICENSE,sha256=m5IaPTxipQwDCpY_YUD927y5QnUzqKGLVUY8E2KxDMk,1165
25
+ motorcortex_python-1.0.0rc1.dist-info/METADATA,sha256=0ZhiD0dkeKZjWLEnncxOk2PRfLDx9t8Lbp8gbJabrW4,6144
26
+ motorcortex_python-1.0.0rc1.dist-info/WHEEL,sha256=hPN0AlP2dZM_3ZJZWP4WooepkmU9wzjGgCLCeFjkHLA,92
27
+ motorcortex_python-1.0.0rc1.dist-info/top_level.txt,sha256=2Glsldo3S13fGB0ub_vogd7y-RQYYNXDjnm-qESmjBY,12
28
+ motorcortex_python-1.0.0rc1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.46.3)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ motorcortex