This release is a pre-release and may not be stable for production use.
Python Client for the OHF Matter Server
A PyPI package (matter-python-client) providing Python bindings for the OHF Matter Server. This is a drop-in replacement for the client portion of python-matter-server, with custom cluster definitions updated to match the Matter.js server.
Origin
The client and common modules were copied from python-matter-server v8.1.2 and modified:
- Source:
matter_server/client/andmatter_server/common/from python-matter-server - Modified:
matter_server/common/custom_clusters.py— updated to match the JS server's cluster definitions - Excluded:
matter_server/server/(the JS server replaces it),common/helpers/logger.py(depends oncoloredlogs, a server-only dependency)
Custom Cluster Changes
| Cluster | Change |
|---|---|
| EveCluster | +8 attributes (getConfig, setConfig, loggingMetadata, loggingData, lastEventTime, statusFault, childLock, rloc16), wattAccumulatedControlPoint type fixed |
| HeimanCluster | Attribute IDs shortened to match JS server |
| NeoCluster | Types changed from float32 to uint |
| Polling | Removed (JS server handles polling natively) |
Package
- PyPI name:
matter-python-client - Python module:
matter_server(same import path aspython-matter-server) - Python: >= 3.12
- Dependencies:
aiohttp,orjson,home-assistant-chip-clusters
npm Scripts (from monorepo root)
# First-time setup: create venv and install with test dependencies
npm run python:install
# Run unit + mock server tests (fast, ~1s)
npm run python:test
# Run full integration tests against real Matter.js server + test device (~40s)
npm run python:test-integration
# Run all Python tests
npm run python:test-all
# Build the PyPI package (.tar.gz + .whl)
npm run python:build
Usage
The package provides the same matter_server.client API as python-matter-server:
import aiohttp
from matter_server.client import MatterClient
async with aiohttp.ClientSession() as session:
client = MatterClient("ws://localhost:5580/ws", session)
await client.connect()
init_ready = asyncio.Event()
listen_task = asyncio.create_task(client.start_listening(init_ready))
await init_ready.wait()
nodes = client.get_nodes()
To reach a server that listens on a unix socket (--listen-address /path/to/socket), pass
unix:///path/to/socket as the server URL. The client then opens its own session on that socket
for the WebSocket and the OTA upload, and the session passed in stays unused.
OHF-only extensions
Beyond the python-matter-server API, the client exposes commands the Matter.js server adds:
-
get_network_topology(refresh=False)— the Thread/Wi-Fi network as a graph (schema 13+) -
upload_ota_file(image)— store a local.otafirmware image in the server's OTA image store (schema 13+). Takes the raw bytes or a path; reserves an upload id over the WebSocket session, then streams the bytes toPOST /ota-upload/<upload_id>. RaisesOtaUploadError(code 101) for a corrupt image, an expired/spent id, or disabled OTA support. -
get_icd_state,register_icd,unregister_icd,resync_icd— ICD Check-In registration -
camera_get_capabilities,camera_start_stream,camera_provide_answer,camera_provide_ice_candidates,camera_stop_stream,camera_snapshot,camera_release_stream— the camera API (schema 14+).camera_get_capabilities,camera_start_stream,camera_stop_streamandcamera_snapshotreturn dataclasses frommatter_server.common.models; the other three returnNone.camera_start_stream'svideo/audiotakeNone(the server decides), aCameraVideoHints/CameraAudioHintsdict, orFalse(no such track).talkback=Truelets the offer ask the camera to play your audio; without it the server makes the offer's audio sections not send, so a browser-stylesendrecvaudio offer goes to the camera asrecvonly.camera_session_endedandcamera_stream_evictedevents arrive asCameraSessionEndedData/CameraStreamEvictedData;webrtc_callbackstays a dict. Errors 102 to 106 (CameraStreamIncompatible, ...) expose their details as attributes, e.g.err.reasonanderr.boundonCameraStreamIncompatibleThe minimal
camera_start_streamcall isnode_id,endpoint_id,stream_usageand your SDP offer: the server reuses or allocates the best stream the camera can serve that still fits what the offer can decode, and adds audio when it can. Passvideo/audiohints only to set hard bounds. A session opened this way is driven withcamera_provide_answer,camera_provide_ice_candidatesandcamera_stop_streamonly, not withsend_webrtc_provider_commandor asend_device_commandEndSession: the server tracks the session and its streams, and only thecamera_*methods keep that record correct. The exception is a re-offer (ICE restart), which goes throughsend_webrtc_provider_command. Seedocs/websockets_api.mdfor the flow and every option.
try:
result = await client.camera_start_stream(node_id, 1, "LiveView", sdp=offer)
except CameraStreamIncompatible as err:
print(err.reason, err.bound)
else:
# The camera's answer arrives as a webrtc_callback "answer" event for this session.
print(result.webrtc_session_id, result.video.codec if result.video else None)
version = await client.upload_ota_file("/path/to/firmware.ota")
print(version.vid, version.pid, version.software_version)
To use this package instead of python-matter-server in the Home Assistant Matter integration, change manifest.json:
- "requirements": ["python-matter-server==8.1.2"],
+ "requirements": ["matter-python-client==1.0.0"],
Testing
The test suite has three layers:
- Import smoke tests (8 tests) — verify all HA integration imports resolve
- Mock server tests (4 tests) — Python client against JS MockMatterServer subprocess
- Integration tests (63 tests) — Python client against real Matter.js server + test device, mirroring the JS
IntegrationTest.ts
Metadata
Release files for matter-python-client 1.5.0a0.dev20261014
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| matter_python_client-1.5.0a0.dev20261014.tar.gz | 242.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| matter_python_client-1.5.0a0.dev20261014-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 583.8 kB
Release files / matter_python_client-1.5.0a0.dev20261014.tar.gz
| Download URL | matter_python_client-1.5.0a0.dev20261014.tar.gz |
|---|---|
| Size | 242.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
362767e61db65659ea21fe61f1f11983dd6e4a56d88cdecfdb256bac6a4885d9
|
|
BLAKE2b-256 checksum How to use checksums |
211d4c6fafc985f85a0ac441cf2b4eeee815c1b036d303f60dd80514a7336f5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 14, 2026.
Transparency logRelease files / matter_python_client-1.5.0a0.dev20261014-py3-none-any.whl
| Download URL | matter_python_client-1.5.0a0.dev20261014-py3-none-any.whl |
|---|---|
| Size | 341.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62018bc77c217826169629c57192a847e1d7841f4ecd7f758dc32067039d9ddd
|
|
BLAKE2b-256 checksum How to use checksums |
6b36f97e47776edcc119c0f127bbc6212e008cb2bde31545f85258c8cb7cf671
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 14, 2026.
Transparency log