Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,56 @@ jobs:
dist/*.tar.gz
dist/*.whl

transport-extras:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- name: no-extras
extras: ""
expect-serial: fail
expect-ble: fail
- name: serial-only
extras: "[serial]"
expect-serial: pass
expect-ble: fail
- name: ble-only
extras: "[ble]"
expect-serial: fail
expect-ble: pass
- name: all
extras: "[all]"
expect-serial: pass
expect-ble: pass
name: transport-extras (${{ matrix.name }})
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: astral-sh/setup-uv@v6

- run: uv venv && uv pip install .${{ matrix.extras }}

- name: serial transport should ${{ matrix.expect-serial }}
run: |
if [ "${{ matrix.expect-serial }}" = "pass" ]; then
.venv/bin/python -c "from smpclient.transport.serial import SMPSerialTransport"
else
! .venv/bin/python -c "from smpclient.transport.serial import SMPSerialTransport" 2>/dev/null
fi

- name: ble transport should ${{ matrix.expect-ble }}
run: |
if [ "${{ matrix.expect-ble }}" = "pass" ]; then
.venv/bin/python -c "from smpclient.transport.ble import SMPBLETransport"
else
! .venv/bin/python -c "from smpclient.transport.ble import SMPBLETransport" 2>/dev/null
fi

- name: udp transport should pass
run: .venv/bin/python -c "from smpclient.transport.udp import SMPUDPTransport"

coverage:
runs-on: ubuntu-latest
steps:
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ If you'd like an SMP CLI application instead of a library, then you should try

`smpclient` is [distributed by PyPI](https://pypi.org/project/smpclient/) and can be installed with `uv`, `pip`, and other dependency managers.

Build with all transports:

```
smpclient[all]
```

Or none (UDP transport only):

```
smpclient
```

Or build with only the transports you need:

```
smpclient[serial] # Serial (UART, USB, CAN)
smpclient[ble] # Bluetooth Low Energy
smpclient[serial,ble] # Serial + BLE
```

The UDP transport has no additional dependencies and is always available.

## User Documentation

Documentation is in the source code so that it is available to your editor.
Expand Down
9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ classifiers = [
"Operating System :: MacOS :: MacOS X",
]
dependencies = [
"pyserial>=3.5",
"smp>=4.0.2",
"intelhex>=2.3.0",
"bleak>=2.0.0",
"async-timeout>=4.0.3; python_version < '3.11'",
]

[project.optional-dependencies]
serial = ["pyserial>=3.5"]
ble = ["bleak>=2.0.0"]
udp = []
all = ["smpclient[serial,ble,udp]"]

[project.urls]
Homepage = "https://www.intercreate.io"
Documentation = "https://intercreate.github.io/smpclient"
Expand All @@ -46,6 +50,7 @@ source = "vcs"

[dependency-groups]
dev = [
"smpclient[all]",
"hatch>=1.14.1",
"mypy>=1.7.0",
"mypy-extensions>=1.0.0",
Expand Down
12 changes: 12 additions & 0 deletions src/smpclient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
Additionally, SMP is extensible, allowing for custom commands to be defined to
meet the specific needs of the product.

### Transports

Transports are optional extras. Install only the transports you need, or all:

```
smpclient[serial]
smpclient[ble]
smpclient[all]
```

The UDP transport has no additional dependencies and is always available.

### Operating Systems

| | Windows 11 (x86) | Ubuntu (Arm/x86) | macOS (Arm/x86) |
Expand Down
13 changes: 9 additions & 4 deletions src/smpclient/transport/ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
from typing import Final, Protocol, TypeGuard
from uuid import UUID

from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
from bleak.args.winrt import WinRTClientArgs
from bleak.backends.client import BaseBleakClient
from bleak.backends.device import BLEDevice
try:
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
from bleak.args.winrt import WinRTClientArgs
from bleak.backends.client import BaseBleakClient
from bleak.backends.device import BLEDevice
except ModuleNotFoundError as e:
if e.name == "bleak":
raise ImportError("BLE transport requires the 'ble' extra. Use smpclient[ble]") from e
raise
from smp import header as smphdr
from typing_extensions import override

Expand Down
9 changes: 8 additions & 1 deletion src/smpclient/transport/serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
from functools import cached_property
from typing import Final

from serial import Serial, SerialException
try:
from serial import Serial, SerialException
except ModuleNotFoundError as e:
if e.name == "serial":
raise ImportError(
"Serial transport requires the 'serial' extra. Use smpclient[serial]"
) from e
raise
from smp import packet as smppacket
from typing_extensions import override

Expand Down
23 changes: 19 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.