Skip to main content

ModemBridge

ModemBridge is an extensible Python SDK for cellular modems and SMS gateway devices.

It provides a unified API for SMS operations while keeping protocol-specific logic inside drivers.

Status

  • Project maturity: alpha (0.1.0)
  • First real driver: ZTE Goform HTTP modem
  • Verified baseline: real-device login, SMS send request, SMS history retrieval, and ID/phone lookup on a live ZTE gateway
  • Important nuance: SEND_SMS returns a request-accepted signal, not final delivery confirmation; the modem’s status endpoint must be checked separately

Features

  • Unified API for sending SMS and reading SMS history
  • Driver registry with alias support
  • Vendor-specific protocol handling isolated in drivers
  • CLI entry point for quick usage (modembridge)
  • Release-ready packaging for GitHub and PyPI

Install

python -m pip install modembridge

With uv:

uv add modembridge

For local development:

python -m pip install -e .[dev]

With uv for this repository:

uv sync

Quick start (Python)

from modembridge import ModemManager, ModemProfile

profile = ModemProfile(
    name="zte_goform",
    host="http://192.168.0.1",
    username="admin",
    password="your-password",
)

manager = ModemManager()
modem = manager.connect(profile)

try:
    result = modem.send_sms("+998901234567", "Hello from ModemBridge")
    print(result)
finally:
    modem.close()

CLI

Send SMS:

modembridge --host http://192.168.0.1 --password your-password --phone +998901234567 --text "Hello"

Read history:

modembridge --host http://192.168.0.1 --password your-password --history

SMS lookup patterns

You can fetch an SMS by its modem ID or filter by phone number when you need to identify a specific sent message.

from modembridge import ModemManager, ModemProfile

profile = ModemProfile(
    name="zte_goform",
    host="http://192.168.0.1",
    username="admin",
    password="your-password",
)

manager = ModemManager()
modem = manager.connect(profile)

one = modem.get_sms_by_id("42")
print(one)

sent_to = modem.get_sms_by_phone("+998901234567", direction="sent")
print(sent_to)

modem.close()

This is useful when you need to confirm whether a specific SMS was sent and to which number it was sent.

Real modem validation

The project has been validated against a live ZTE Goform modem using the configured modem password from environment variables.

uv run --env-file .env python examples/real_modem_check.py

Observed live-device behavior:

  • probe() returned True on the real modem
  • get_sms_history() returned real SMS entries from the modem
  • send_sms() returned ok=True with a request-accepted result
  • the modem reported sms_cmd_status_result=1 immediately after send, which maps to queued rather than final delivery
  • get_sms_by_id() and get_sms_by_phone() successfully returned the just-sent message from history

This confirms that the SDK works with the live device and that delivery status must be checked separately from the immediate send response.

Architecture

ModemBridge keeps core and driver concerns separate:

  1. Core: profile model, manager, modem abstraction
  2. Driver: protocol-specific login, payloads, and parsers
  3. Registry: driver lookup and aliases

Current included driver:

  • zte_goform

Adding new drivers (future-proof workflow)

  1. Implement a driver class that supports:
    • send_sms(phone, text, retries=3)
    • get_sms_history()
    • optional probe()
    • optional close()
  2. Register manually:
from modembridge import ModemManager

manager = ModemManager(load_external_drivers=False)
manager.register_driver("my_driver", MyDriver, aliases=["my_vendor"])
  1. Or register via Python entry points in your separate package:
[project.entry-points."modembridge.drivers"]
my_driver = "my_package.driver:MyDriver"

When ModemManager() starts, external drivers from modembridge.drivers entry-point group are auto-loaded.

For a focused walkthrough, see DRIVER_GUIDE.md.

Security and privacy

  • Never commit real passwords, IMSI/IMEI, SIM numbers, or session cookies.
  • Use environment variables or secret managers for runtime credentials.
  • Keep logs and bug reports sanitized.

See SECURITY.md for reporting guidance.

Development

Run tests:

python -m unittest discover -s tests -v

With uv:

uv run python -m unittest discover -s tests -v

Build package:

python -m build
python -m twine check dist/*

With uv:

uv build
uv run python -m twine check dist/*

Releasing

Release steps are documented in RELEASE.md. For uv + .env publish flow, see docs/uv-publish.md.

Package

Creator

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

modembridge-0.1.1.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

modembridge-0.1.1-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file modembridge-0.1.1.tar.gz.

File metadata

  • Download URL: modembridge-0.1.1.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for modembridge-0.1.1.tar.gz
Algorithm Hash digest
SHA256 315933637c1c4b83a78567594efa4705cfc0861d7add6fae6101f24cd2dcabc5
MD5 4dc2efed659cbbaad37883ee5938ce9a
BLAKE2b-256 4bae089397e505e336149d74fa93d05afea0c64007ae8066c277d1c8036d866d

See more details on using hashes here.

File details

Details for the file modembridge-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: modembridge-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for modembridge-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dc1f873494e1c09c18e1a808a97bd0f1902ec01f557f0b623c6c06e0056815a7
MD5 d5e5d3c0e9620b5845553a630c609db5
BLAKE2b-256 29d208d348a32abde98bc8d177e453476220742bd4189e7297ffbbb77cc39330

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page