Skip to content

Commit b8a5d27

Browse files
committed
BREAKING: ble and serial dependencies are optional
Use [ble], [serial], or [all] to enable the transports that are required. Existing projects are encouraged to use [all] to minimize migration friction.
1 parent fc556c0 commit b8a5d27

7 files changed

Lines changed: 125 additions & 11 deletions

File tree

.github/workflows/test.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,56 @@ jobs:
3535
dist/*.tar.gz
3636
dist/*.whl
3737
38+
transport-extras:
39+
runs-on: ubuntu-latest
40+
strategy:
41+
matrix:
42+
include:
43+
- name: no-extras
44+
extras: ""
45+
expect-serial: fail
46+
expect-ble: fail
47+
- name: serial-only
48+
extras: "[serial]"
49+
expect-serial: pass
50+
expect-ble: fail
51+
- name: ble-only
52+
extras: "[ble]"
53+
expect-serial: fail
54+
expect-ble: pass
55+
- name: all
56+
extras: "[all]"
57+
expect-serial: pass
58+
expect-ble: pass
59+
name: transport-extras (${{ matrix.name }})
60+
steps:
61+
- uses: actions/checkout@v4
62+
with:
63+
fetch-depth: 0
64+
65+
- uses: astral-sh/setup-uv@v6
66+
67+
- run: uv venv && uv pip install .${{ matrix.extras }}
68+
69+
- name: serial transport should ${{ matrix.expect-serial }}
70+
run: |
71+
if [ "${{ matrix.expect-serial }}" = "pass" ]; then
72+
.venv/bin/python -c "from smpclient.transport.serial import SMPSerialTransport"
73+
else
74+
! .venv/bin/python -c "from smpclient.transport.serial import SMPSerialTransport" 2>/dev/null
75+
fi
76+
77+
- name: ble transport should ${{ matrix.expect-ble }}
78+
run: |
79+
if [ "${{ matrix.expect-ble }}" = "pass" ]; then
80+
.venv/bin/python -c "from smpclient.transport.ble import SMPBLETransport"
81+
else
82+
! .venv/bin/python -c "from smpclient.transport.ble import SMPBLETransport" 2>/dev/null
83+
fi
84+
85+
- name: udp transport should pass
86+
run: .venv/bin/python -c "from smpclient.transport.udp import SMPUDPTransport"
87+
3888
coverage:
3989
runs-on: ubuntu-latest
4090
steps:

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,28 @@ If you'd like an SMP CLI application instead of a library, then you should try
1616

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

19+
Build with all transports:
20+
21+
```
22+
smpclient[all]
23+
```
24+
25+
Or none (UDP transport only):
26+
27+
```
28+
smpclient
29+
```
30+
31+
Or build with only the transports you need:
32+
33+
```
34+
smpclient[serial] # Serial (UART, USB, CAN)
35+
smpclient[ble] # Bluetooth Low Energy
36+
smpclient[serial,ble] # Serial + BLE
37+
```
38+
39+
The UDP transport has no additional dependencies and is always available.
40+
1941
## User Documentation
2042

2143
Documentation is in the source code so that it is available to your editor.

pyproject.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ classifiers = [
2121
"Operating System :: MacOS :: MacOS X",
2222
]
2323
dependencies = [
24-
"pyserial>=3.5",
2524
"smp>=4.0.2",
2625
"intelhex>=2.3.0",
27-
"bleak>=2.0.0",
2826
"async-timeout>=4.0.3; python_version < '3.11'",
2927
]
3028

29+
[project.optional-dependencies]
30+
serial = ["pyserial>=3.5"]
31+
ble = ["bleak>=2.0.0"]
32+
udp = []
33+
all = ["smpclient[serial,ble,udp]"]
34+
3135
[project.urls]
3236
Homepage = "https://www.intercreate.io"
3337
Documentation = "https://intercreate.github.io/smpclient"
@@ -46,6 +50,7 @@ source = "vcs"
4650

4751
[dependency-groups]
4852
dev = [
53+
"smpclient[all]",
4954
"hatch>=1.14.1",
5055
"mypy>=1.7.0",
5156
"mypy-extensions>=1.0.0",

src/smpclient/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@
77
Additionally, SMP is extensible, allowing for custom commands to be defined to
88
meet the specific needs of the product.
99
10+
### Transports
11+
12+
Transports are optional extras. Install only the transports you need, or all:
13+
14+
```
15+
smpclient[serial]
16+
smpclient[ble]
17+
smpclient[all]
18+
```
19+
20+
The UDP transport has no additional dependencies and is always available.
21+
1022
### Operating Systems
1123
1224
| | Windows 11 (x86) | Ubuntu (Arm/x86) | macOS (Arm/x86) |

src/smpclient/transport/ble.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
from typing import Final, Protocol, TypeGuard
88
from uuid import UUID
99

10-
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
11-
from bleak.args.winrt import WinRTClientArgs
12-
from bleak.backends.client import BaseBleakClient
13-
from bleak.backends.device import BLEDevice
10+
try:
11+
from bleak import BleakClient, BleakGATTCharacteristic, BleakScanner
12+
from bleak.args.winrt import WinRTClientArgs
13+
from bleak.backends.client import BaseBleakClient
14+
from bleak.backends.device import BLEDevice
15+
except ImportError as _e:
16+
raise ImportError(
17+
"BLE transport requires the 'ble' extra. Install with: pip install smpclient[ble]"
18+
) from _e
1419
from smp import header as smphdr
1520
from typing_extensions import override
1621

src/smpclient/transport/serial.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111
from functools import cached_property
1212
from typing import Final
1313

14-
from serial import Serial, SerialException
14+
try:
15+
from serial import Serial, SerialException
16+
except ImportError as _e:
17+
raise ImportError(
18+
"Serial transport requires the 'serial' extra. Install with: pip install smpclient[serial]"
19+
) from _e
1520
from smp import packet as smppacket
1621
from typing_extensions import override
1722

uv.lock

Lines changed: 19 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)