Python interface to access DuetSoftwareFramework
Project description
Duet Software Framework Python Bindings
dsf-python provides Python bindings for the Duet Software Framework control server.
It exposes the DSF socket protocol as Python connection classes, typed object model
classes, command builders, and helpers for custom HTTP endpoints.
This project is also published on PyPI.
Useful links:
What The Library Contains
The top-level package is organised around the main DSF workflows.
dsf.connections: socket-based client connections for commands, subscriptions, and code interceptiondsf.commands: request payload builders for low-level DSF commandsdsf.object_model: the typed DSF object model and related enumsdsf.http: helpers for custom HTTP and WebSocket endpoints exposed through DSFdsf.exceptions: shared exception types raised by connection classes
Installation
The package can be installed from source:
python3 setup.py install
Or with pip:
python3 -m pip install dsf-python
Most code using this library must run on a system with Duet Software Framework installed and with permission to access the DSF UNIX socket.
Quick Start
Run A Simple Command
Use CommandConnection to send general-purpose commands such as G-code or to
request the full object model on demand.
from dsf.connections import CommandConnection
connection = CommandConnection()
connection.connect()
response = connection.perform_simple_code("M115")
print(response.result)
connection.close()
Read The Object Model Once
from dsf.connections import CommandConnection
connection = CommandConnection()
connection.connect()
object_model = connection.get_object_model()
print(object_model.state.status)
print(object_model.move.axes[0].letter)
connection.close()
Subscribe To Object Model Updates
Use SubscribeConnection when you want DSF to push object model updates over a
subscription socket.
from dsf.connections import SubscribeConnection, SubscriptionMode
subscription = SubscribeConnection(SubscriptionMode.PATCH)
subscription.connect()
object_model = subscription.get_object_model()
while True:
object_model = subscription.get_object_model()
In SubscriptionMode.PATCH, the first get_object_model() call reads the full
model. Later calls reuse an internal cached model and apply one queued patch if
available.
Connections
CommandConnection
CommandConnection is the general-purpose connection type. It is used for:
- sending simple G-code
- requesting the full object model
- working with files, packages, plugins, and user sessions through DSF commands
- issuing lower-level requests through the command helpers in
dsf.commands
Choose this connection when you want request-response behaviour and do not need streamed updates.
SubscribeConnection
SubscribeConnection receives streamed object model updates from DSF. It supports:
SubscriptionMode.FULL: every update is a full object modelSubscriptionMode.PATCH: every update is a partial JSON fragment
Key-Based Callbacks
SubscribeConnection.subscribe_to_keys() can run callbacks synchronously when
selected object model paths appear in a patch update processed by get_object_model().
Key paths use dot notation and can include list indexes:
state.upTimeheat.heaters.0.currentmove.axes.2.userPosition
Use ^ in a list position to match any changed index:
heat.heaters.^.currenttools.^.state
Callbacks always receive keyword arguments:
key: the subscribed key path that matcheddata: the changed value found at that pathindices: a tuple of matched wildcard indexes, orNonewhen the key does not use^
from dsf.connections import SubscribeConnection, SubscriptionMode
def handle_change(*, key, data, indices):
print(key, data, indices)
subscription = SubscribeConnection(SubscriptionMode.PATCH)
subscription.connect()
subscription.get_object_model()
unsubscribe = subscription.subscribe_to_keys(
["heat.heaters.0.current", "state.upTime"],
handle_change,
)
while True:
object_model = subscription.get_object_model()
Wildcard example:
def handle_any_heater(*, key, data, indices):
print(key, indices, data)
subscription.subscribe_to_keys(
["heat.heaters.^.current"],
handle_any_heater,
)
InterceptConnection
InterceptConnection is used for custom code handling and code interception. Use it
when a plugin needs to receive G/M/T-code events before or after the firmware handles them.
Typical use cases include:
- implementing custom M-codes
- inspecting or rewriting commands
- reacting to executed code notifications
See examples/custom_m_codes.py for a complete example.
Object Model
The dsf.object_model package mirrors the DSF object model in typed Python classes.
It lets you work with structured properties instead of manually traversing raw JSON.
Examples:
print(object_model.boards[0].name)
print(object_model.state.up_time)
print(object_model.move.axes[0].letter)
print(object_model.tools[0].state)
Object model instances support JSON-driven updates:
object_model.update_from_json({"state": {"upTime": 1234}})
print(object_model.state.up_time)
This is the mechanism used internally when patch subscriptions are applied.
Commands
The dsf.commands package contains low-level command builders for code execution,
file access, plugins, packages, object model manipulation, and other DSF protocol
requests.
Most users should start with the higher-level methods on CommandConnection or
BaseCommandConnection. Reach for dsf.commands directly when you need explicit
control over the payload sent to DSF.
Custom HTTP Endpoints
The dsf.http module contains helpers for custom HTTP and WebSocket endpoints.
This is useful when a DSF plugin needs to expose an HTTP route that is handled by
Python code.
Key types include:
HttpEndpointUnixSocketHttpEndpointConnectionReceivedHttpRequestHttpResponseType
See examples/custom_http_endpoint.py for a practical example.
Included Examples
The examples/ directory demonstrates the main workflows supported by the library.
send_simple_code.py: send G-code over a command connectionsubscribe_object_model.py: subscribe to object model updatescustom_m_codes.py: intercept and implement custom M-codescustom_http_endpoint.py: serve a custom HTTP endpoint through DSF
API Reference
The Sphinx docs expose the package API for the major public modules:
dsfdsf.connectionsdsf.commandsdsf.object_modeldsf.http
Development Notes
The library talks to DSF using the configured UNIX socket path. By default this is
resolved from the DSF config and falls back to /run/dsf/dcs.sock.
If you are extending the library itself, the test suite under tests/ contains
mock socket servers and object model fixtures that are useful for validating new
connection behaviour.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dsf_python-3.7.0b1.tar.gz.
File metadata
- Download URL: dsf_python-3.7.0b1.tar.gz
- Upload date:
- Size: 95.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d73cc48db62444b376c0f5e493165a6c39b62732871c22257a0b6a795984c3c
|
|
| MD5 |
90827e7624a6d7902772c7bda2b0a1a9
|
|
| BLAKE2b-256 |
00f923ca63c88b54b7b12ec9784feabe16a752978d9f7d5ef42646f168b1d2ff
|
Provenance
The following attestation bundles were made for dsf_python-3.7.0b1.tar.gz:
Publisher:
publish-to-pypi.yml on Duet3D/dsf-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dsf_python-3.7.0b1.tar.gz -
Subject digest:
3d73cc48db62444b376c0f5e493165a6c39b62732871c22257a0b6a795984c3c - Sigstore transparency entry: 2025011196
- Sigstore integration time:
-
Permalink:
Duet3D/dsf-python@f6c02a8b936e51c4f15f61cb47694b1eb80cfaa2 -
Branch / Tag:
refs/tags/3.7.0-beta.1 - Owner: https://github.com/Duet3D
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@f6c02a8b936e51c4f15f61cb47694b1eb80cfaa2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dsf_python-3.7.0b1-py3-none-any.whl.
File metadata
- Download URL: dsf_python-3.7.0b1-py3-none-any.whl
- Upload date:
- Size: 129.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d32a3b16085ab4332ab1d165fec49fb83205926d35b643bfb1497808585182d
|
|
| MD5 |
c4e1bd7784b524daac510cfaf70f5bf0
|
|
| BLAKE2b-256 |
bd817a74b7da3b139c3f410cc5fc2b8844d98d29e2cc5abd542d9ff3acb8d8a5
|
Provenance
The following attestation bundles were made for dsf_python-3.7.0b1-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on Duet3D/dsf-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dsf_python-3.7.0b1-py3-none-any.whl -
Subject digest:
0d32a3b16085ab4332ab1d165fec49fb83205926d35b643bfb1497808585182d - Sigstore transparency entry: 2025011387
- Sigstore integration time:
-
Permalink:
Duet3D/dsf-python@f6c02a8b936e51c4f15f61cb47694b1eb80cfaa2 -
Branch / Tag:
refs/tags/3.7.0-beta.1 - Owner: https://github.com/Duet3D
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@f6c02a8b936e51c4f15f61cb47694b1eb80cfaa2 -
Trigger Event:
release
-
Statement type: