Skip to main content

YAThorLib

Python 3.13+ asynchronous Thorlabs APT communications, implemented directly over Linux serial ports. The runtime uses neither Windows DLLs nor Kinesis, Wine, .NET or Ghidra.

Work in progress: this is a protocol implementation with selected typed device APIs, not yet a complete replacement for Kinesis. Hardware validation so far: two KDC101 units with an MTS100/M-Z8 stage (read, enable, home, moves, jog, stops, status updates, timeouts); no other model has been tested. Device error replies and a mid-move unplug are untested. The command catalog records documentation applicability; it does not certify a controller or firmware version. See support coverage and reverse engineering evidence.

Install

python3.13 -m venv .venv
. .venv/bin/activate
python -m pip install .

The controller must already appear as a Linux serial device (usually /dev/ttyUSB*). Use the appropriate distribution serial-device permissions and ensure another process is not using the port. discover() enumerates candidate ports without opening them. Its USB ID filter comes from the supplied driver INF files; a matching ID does not establish model compatibility. Devices without a working kernel serial interface need further driver work.

import asyncio
from yathorlib import Connection, device, discover

async def main():
    print(discover())
    async with await Connection.open_serial('/dev/ttyUSB0') as connection:
        motor = device(connection, 'KDC101')
        print(await motor.hardware_info())
        print(await motor.position())  # integer device units

asyncio.run(main())

Opening uses 115200 baud, 8N1, RTS/CTS, exclusive serial access and an initial buffer purge. Model, channel, and rack bay are explicit. Opening or constructing an endpoint does not enable outputs, home a stage, or move it.

Device APIs

device(connection, model, channel=1, destination=0x50) chooses a convenience class from documented capabilities. Motor supplies position, status, home, move_absolute, move_relative, jog and stop; Piezo supplies raw voltage/position and control mode. Other APIs cover selected inertial motor, NanoTrak, solenoid, strain gauge, detector, temperature, laser, liquid crystal and encoder operations. Their exact scope is in support.md.

Motion values are device units. Stage scaling is not inferred from a controller model. UnitScale accepts explicit, independently established conversion factors. Configure the stage, limits and homing parameters as required by its documentation before moving. In particular, a controller supporting a command does not prove it has the correct settings for the attached stage.

# Explicit motion operation, only after configuring the actual stage:
await motor.move_absolute(1000, timeout=30)
# Another coroutine can interrupt a pending move:
await motor.stop()

Requests serialize on each connection because APT has no transaction identifiers. Events and stop writes remain concurrent. A request timeout or cancellation after sending closes the connection to prevent a late response satisfying a later request. Closing a connection does not stop hardware motion. A motor MOVE_STOPPED response raises MotionInterrupted during a waiting move.

Select the motor status layout explicitly (await motor.status(kind='dc') or kind='stepper'). A shared message identifier can have different payload layouts across controller families.

Raw messages and events

from yathorlib import Message, command

print(command('MOT_REQ_POSCOUNTER'))  # ID, source page and evidence basis
reply = await connection.request(Message(0x0411, param1=1), 0x0412)

# Subscribe before starting the operation producing the events.
async with connection.events(max_queue=256) as events:
    await connection.send(Message(0x0411, param1=1))
    message = await anext(events)

Device.send and Device.request check model applicability; callers supply exact raw fields. Connection permits arbitrary Message packets for further investigation. Layouts not implemented as typed APIs are not automatically decoded by the catalog. Unknown or ambiguous numeric identifiers are rejected by catalog lookup.

device.updates(acknowledgement='MOT_ACK_USTATUSUPDATE') manages start/stop and an ACK heartbeat; choose the ACK documented for the actual controller. Overlapping update contexts for one hardware endpoint are rejected. Queue overflow raises EventOverflow rather than silently losing messages. Raw events() does not start polling or send ACKs.

Rack(connection).bay(index, model) addresses rack bays starting at index zero. Bay address and device channel are distinct. Connection.open_tcp is for a transparent APT byte-stream bridge; native Kinesis network hub discovery and negotiation are not implemented. A custom asynchronous Transport can also be supplied.

Development

python -m pip install '.[dev]'
python -m pytest -q
python tools/build_catalog.py
python -m build

Tests include golden wire packets, fragmented reads, cancellation, error routing, unsolicited events, a TCP loopback and a Linux pseudo-terminal using the real serial transport. They do not substitute for physical-device tests. The local REA/Ghidra setup is used only to investigate supplied artifacts; see the research guide for reproduction.

License

YAThorLib code is MIT licensed. Thorlabs software and reference materials used for the research (Kinesis DLLs, headers, drivers) are third-party, are not part of this repository (REA Source/ is git-ignored) and are not included in the PyPI distributions. See reverse engineering for how to obtain them.

Release instructions: publishing guide.

Metadata

Release files for yathorlib 0.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 yathorlib 0.2.0
File Size Uploaded Provenance Actions
yathorlib-0.2.0.tar.gz 45.4 kB With provenance Details for yathorlib-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for yathorlib 0.2.0
File Interpreter ABI Platform Actions
yathorlib-0.2.0-py3-none-any.whl Python 3 none any Details for yathorlib-0.2.0-py3-none-any.whl

Total release size: 77.0 kB

Release files / yathorlib-0.2.0.tar.gz

Download URL yathorlib-0.2.0.tar.gz
Size 45.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5042affec04e0d27f929cd1b8a1b9c46359e922a8538eea6a90ad86ee266c320
BLAKE2b-256 checksum
How to use checksums
826ddf368e00b93787b9372998943b37609a751e3440e15002887ce146ba2879
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / yathorlib-0.2.0-py3-none-any.whl

Download URL yathorlib-0.2.0-py3-none-any.whl
Size 31.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1ef2b6859529fe385545feec0fdb17b9ebee50797bfb0b1bf4af267a261b851
BLAKE2b-256 checksum
How to use checksums
3c12f04e8650be55b9500e5038550b3fc845f0a19adfd440eb4f3b026943fe8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Security for yathorlib 0.2.0

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for yathorlib-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

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