Skip to content

feat: Python xbot_service_interface library#25

Merged
ClemensElflein merged 5 commits into
mainfrom
feature/python-service-interface
May 22, 2026
Merged

feat: Python xbot_service_interface library#25
ClemensElflein merged 5 commits into
mainfrom
feature/python-service-interface

Conversation

@ClemensElflein
Copy link
Copy Markdown
Member

Summary

  • Runtime serialization — no codegen, no generated files to maintain
  • Two modes: Mode 1 (schema provided, type+version validated on connect) and Mode 2 (schema discovered from advertisement CBOR, full JSON including registers and enums)
  • Dynamic send_{input_name}(value) methods and on_{output_name}_changed callbacks via __getattr__/__setattr__ — mirrors C++ generated API in snake_case
  • service.registers['Name'] = value dict-like proxy; sent immediately if connected, queued for next CONFIGURATION_REQUEST otherwise
  • Transaction context manager: with service.transaction(): ...
  • Full connection lifecycle: discovery → claim → config → heartbeat watchdog → reconnect on timeout

Test plan

  • Install dependency: pip install cbor2
  • Start EchoService (C++ example binary)
  • Run python examples/echo_with_schema.py — Mode 1: schema validation, register config, echo callbacks
  • Run python examples/echo_no_schema.py — Mode 2: schema from advertisement, no local JSON needed
  • Kill EchoService mid-run, verify disconnect log, restart and verify reconnect

Runtime serialization (no codegen) for connecting to xBot services from Python.
Supports both schema-validated (Mode 1) and schema-from-advertisement (Mode 2) modes.

- datatypes.py: XbotHeader/DataDescriptor/ClaimPayload struct formats, MessageType enum
- serialization.py: type string parser, pack/unpack for all C primitives, char arrays, enums
- schema.py: ServiceSchema wrapping service.json, lookup by id/name/snake_name
- discovery.py: multicast listener on 233.255.255.0:4242, CBOR advertisement parse
- io.py: unicast UDP, claim flow, heartbeat watchdog, send_data/send_transaction
- interface.py: ServiceInterface with dynamic send_*/on_*_changed dispatch, RegisterProxy,
  transaction context manager
- manager.py: XbotServiceIo tying discovery + IO + interfaces together
- examples/: echo_with_schema.py (Mode 1) and echo_no_schema.py (Mode 2)
@ClemensElflein ClemensElflein force-pushed the feature/python-service-interface branch from b692c2a to d34db42 Compare May 20, 2026 23:58
Add 331 tests across datatypes, serialization, schema, interface, io and discovery.

Bugs fixed:
- serialization: parse_type_string regex rejected uppercase enum type names
  (e.g. MotorMode) — changed [a-z_] to [a-zA-Z_]
- discovery: _handle_packet crashed when malformed CBOR decoded to a non-dict
  object instead of raising — added isinstance(msg, dict) guard
The service resets all registers to defaults before applying any config
transaction (HandleConfigurationTransaction calls loadConfigurationDefaults
then allRegistersValid). Sending a single-register transaction left required
registers invalid, causing 'Configuration message did not contain all
required registers' on every live register update.
- Rename top-level directory from xbot_py to xbot_service_interface to
  match library name and C++ sibling convention (libxbot-service-interface)
- Fix pyproject.toml build-backend (setuptools.backends.legacy → build_meta)
- Add full PyPI metadata: author, license, classifiers, project URLs
- Add README.md for PyPI landing page with API overview and examples
- Add py.typed marker for PEP 561 type checking support
- Update .gitignore to exclude dist/, build/, *.egg-info/
- Verified: python -m build produces sdist + wheel successfully
@ClemensElflein ClemensElflein merged commit f1af44a into main May 22, 2026
2 checks passed
@ClemensElflein ClemensElflein deleted the feature/python-service-interface branch May 22, 2026 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant