CometTextel — Python (thin FFI)
Thin ctypes binding to the same C ABI as the C SDK and CometTextel.NET (c_api.h).
This is not a second native library: it runtime-loads comettextel.dll / libcomettextel.so.
Covers PDU helpers and GsmModem (open / send / list / delete).
Hardware modem tests are optional; smoke tests run without a device.
Layout
sdk/python/
├── comettextel/ # package (ctypes + PDU + modem)
├── examples/
│ ├── pdu_example.py # encode / decode + self-check
│ └── modem_example.py # list / send / delete
├── tests/
│ ├── test_pdu.py
│ └── test_modem.py
└── README.md
Prerequisites
| Item | Detail |
|---|---|
| Python | 3.10+ (3.13 verified) |
| Native | C SDK shared library (comettextel.dll or libcomettextel.so) |
| Modem (optional) | AT modem in PDU mode (e.g. COM3, /dev/ttyUSB0) |
Download comettextel-c-sdk-* from CI Artifacts or a GitHub Release, or use a local CMake build.
Finding the library
Search order:
- Explicit path passed to
comettextel.pdu.load_library(...) - Environment variable
COMETTEXTEL_LIB(shared-library file or a directory containing it — including versioned Linux sonames such aslibcomettextel.so.1.3.0) - Wheel-embedded
_native/<platform>/(CI platform wheels) - Current working directory
- Nearby build / artifact folders (
build-c-sdk/Release,artifact/comettextel-c-sdk-*/…)
# Windows
$env:COMETTEXTEL_LIB = "D:\path\to\comettextel.dll"
# Linux
export COMETTEXTEL_LIB=/path/to/libcomettextel.so
Wheels
CI builds platform wheels that embed the matching C ABI shared library:
| Artifact | Tag |
|---|---|
comettextel-python-wheel-windows |
win_amd64 |
comettextel-python-wheel-linux |
linux_x86_64 |
Local pack (after a C SDK stage):
python sdk/python/scripts/stage_native.py --from artifact/comettextel-c-sdk-windows-x64
python -m pip install build
python -m build --wheel --outdir dist sdk/python
python sdk/python/scripts/stage_native.py --clean
pip install dist/comettextel-*.whl
Editable / source installs without a staged _native still need COMETTEXTEL_LIB or a nearby build.
PDU example
cd sdk\python
python examples\pdu_example.py
python examples\pdu_example.py 886912345678 "Hello" 886932000000
python examples\pdu_example.py 886912345678 "測試中文簡訊" 886932000000
Modem example
python examples\modem_example.py list COM3
python examples\modem_example.py send COM3 886932000000 886912345678 "Hello"
python examples\modem_example.py delete COM3 1
list rejoins complete concatenated SMS sets (concat_seq == 0 / Message.is_reassembled_concat).
Tests
cd sdk\python
pip install pytest
pytest -q
API sketch
from comettextel import DCS_UCS2, GsmModem, decode, encode_submit_segments
parts = encode_submit_segments("886912345678", "Hello", "886932000000", DCS_UCS2)
msg = decode(parts[0])
with GsmModem() as modem:
modem.open("COM3", 115200)
modem.send("886912345678", "Hello from Python", smsc="886932000000")
for m in modem.list():
print(m.index, m.peer_address, m.user_data, m.is_reassembled_concat)
All text at the native boundary is UTF-8. Do not reimplement PDU codecs in Python; if the C ABI changes, update this package only.
GSM 7-bit (DCS_GSM7)
Maps UTF-8 through GSM 03.38 (default alphabet + ESC extension). Examples: []{}\~^|€.
Unsupported glyphs (e.g. Chinese) raise CometTextelError / encode status — use DCS_UCS2.
Extension characters consume two septets; concat auto-split will not break an ESC pair.
from comettextel import DCS_GSM7, decode, decode_status_report, encode_submit
hex_pdu = encode_submit("886912345678", "Cost: 10€ [ok]", "886932000000", DCS_GSM7)
print(decode(hex_pdu).user_data)
Status reports can be decoded separately:
report = decode_status_report(
"00022A0C91889621436587215070418045232150704180452300"
)
print(report.message_reference, hex(report.tp_status), report.recipient_address)
api_version() reports the native C ABI feature version. A legacy DLL without
the version export is treated as version 1; Status Report decoding then raises
CometTextelError with Status.UNSUPPORTED while existing APIs remain usable.
Validity Period / Status Report
The default submit APIs omit TP-VP, allowing the SMSC to apply its default
validity period. To set a GSM relative TP-VP, pass an octet from 0 to 255;
0 means five minutes. request_status_report=True sets TP-SRR:
hex_pdu = encode_submit(
"886912345678", "OTP 123456", "886932000000", DCS_GSM7,
relative_validity_period=0x8F,
request_status_report=True,
)
The same keyword arguments are available on encode_submit_segments() and
GsmModem.send(). After requesting a report, call
modem.poll_status_report() (C ABI v3) to drain +CDS URCs. Older native
libraries raise Status.UNSUPPORTED for that method while other APIs remain usable.
See also
Metadata
Release files for comettextel 1.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| comettextel-1.7.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| comettextel-1.7.0-py3-none-manylinux_2_34_x86_64.whl | Python 3 | none | Linux glibc 2.34+ x86-64 | Details |
Total release size: 161.3 kB
Release files / comettextel-1.7.0-py3-none-win_amd64.whl
| Download URL | comettextel-1.7.0-py3-none-win_amd64.whl |
|---|---|
| Size | 66.2 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e487554a1e1785a77599e1026bc451b5c79e8d34df226a8c4f07e1f97e0b6d89
|
|
BLAKE2b-256 checksum How to use checksums |
3fa94e21b214c33f838f5f17778eb6f85e9dc23c37731977757182bc9e1540dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|
Release files / comettextel-1.7.0-py3-none-manylinux_2_34_x86_64.whl
| Download URL | comettextel-1.7.0-py3-none-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 95.2 kB |
| Tags | Linux glibc 2.34+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
8ce7e091fe7e13a696b6c80065a1d772a75510e3ae34b70636417063c46a1496
|
|
BLAKE2b-256 checksum How to use checksums |
c1f72a8f4189de926d2b231699c0927ffbc45b77d94f60f00ca50654fa4e1764
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|