Skip to main content

Python client for the Green Relay SMS microservice API

Project description

green-relay (Python client)

A small, typed Python client for the Green Relay SMS microservice API. The design follows the same shape as the OpenAI Python client: one GreenRelay object configured with a base URL and API key, with endpoints grouped into resource namespaces (messages, health, events).

Install

uv sync

The client uses requests for HTTP.

Quick start

from green_relay import GreenRelay

client = GreenRelay(api_key="your-key", base_url="http://localhost:8080")

# Queue a message (returns immediately, 202)
resp = client.messages.send(to="+14155552671", body="Hello")
print(resp.id, resp.status, resp.parts)

# Send and wait for the delivery outcome
result = client.messages.send_sync(to="+14155552671", body="Hello")
if result.queued:
    print("still queued:", result.id)
else:
    print("delivered:", result.status, result.reference)

# Look up an outbound message
msg = client.messages.get(resp.id)
print(msg.status, msg.error_code)

Reading messages: two ways

1. Synchronous

Poll inbound messages, or iterate the event stream directly:

# Polling
for inbound in client.messages.list_inbound(limit=50):
    print(inbound.from_number, inbound.body)

# Blocking iterator over the live event stream
for event in client.events.stream():
    print(event.name, event.data)

2. Callback / event listener

Run the stream in a background thread and dispatch to callbacks:

def on_sms(event):
    print("inbound:", event.from_, event.body)

def on_status(event):
    print("status:", event.id, event.status)

listener = client.events.listen(
    on_inbound_sms=on_sms,
    on_message_status=on_status,
)

# ... do other work ...

listener.stop()

Health and status

health = client.health.get()        # works even when degraded/unhealthy
print(health.health, health.serial_connected)

status = client.health.status()
print(status.signal_percent, status.operator)

Error handling

Transport problems (connection refused, timeouts, DNS failures) propagate as the standard requests exceptions. Invalid arguments raise ValueError. A non-success HTTP response raises a single APIError that mirrors the service's JSON error body (error message + offending fields), with retry_after populated on 429/503.

import requests
from green_relay import APIError

try:
    client.messages.send(to="bad", body="hi")
except APIError as exc:
    print(exc.status_code, exc.error, exc.fields)
    if exc.retry_after is not None:
        print("retry after", exc.retry_after, "seconds")
except requests.RequestException as exc:
    print("could not reach the server:", exc)

Logging

The library follows the standard convention: it attaches a NullHandler and emits only DEBUG request logs under the green_relay logger. Configure logging in your application to see them:

import logging
logging.basicConfig(level=logging.DEBUG)

Development

This project uses uv for dependency management and ruff for linting and formatting. Run everything from the python-client directory.

Install dependencies (including dev tools):

uv sync --all-groups

Lint, format, and test:

uv run ruff check .          # lint
uv run ruff check --fix .    # lint and auto-fix
uv run ruff format .         # format
uv run ruff format --check . # verify formatting (used in CI)
uv run pytest                # run the test suite

CI runs all of these on pushes and pull requests that touch python-client/ via .github/workflows/python-client.yml. See tests/README.md for the test layout and examples/README.md for runnable examples.

Releasing to PyPI

Publishing is automated by .github/workflows/python-client-publish.yml, which builds the sdist and wheel with uv build and uploads them to PyPI using Trusted Publishing (OIDC, no stored API token).

One-time setup: on PyPI, add a trusted publisher for the green-relay project pointing at this repository, the python-client-publish.yml workflow, and the pypi environment.

To cut a release:

  1. Bump the version in pyproject.toml (uv version <new-version> updates it).

  2. Commit the bump.

  3. Tag it with a python-v prefix matching the version and push the tag:

    git tag python-v0.1.0
    git push origin python-v0.1.0
    

The workflow verifies the tag matches the pyproject.toml version, re-runs the lint/format/test checks, builds, and publishes. It can also be run manually via the Actions tab (workflow_dispatch).

Project details


Download files

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

Source Distribution

green_relay-0.1.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

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

green_relay-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file green_relay-0.1.0.tar.gz.

File metadata

  • Download URL: green_relay-0.1.0.tar.gz
  • Upload date:
  • Size: 38.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for green_relay-0.1.0.tar.gz
Algorithm Hash digest
SHA256 690f013260f68a04338dc80e8d34b05dde6ae355109978da1763194618596800
MD5 e74c3041b2d79a766adf99f47d1a0dfa
BLAKE2b-256 dcbc831be0a05a0ffca690745ee90c2229605c113b1a6389be7955fd25a1a498

See more details on using hashes here.

Provenance

The following attestation bundles were made for green_relay-0.1.0.tar.gz:

Publisher: python-client-publish.yml on Greenstorm5417/green_relay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file green_relay-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: green_relay-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for green_relay-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 96076745d3b1803b32def74e751285d4131fcfe8c2a53decbffeec63514361f7
MD5 8c597c47d1ba8f5d81e4026067e160a4
BLAKE2b-256 88ee4c0c59f8e5d7902ae751fb0f4cf0e0f5b8862fffacb29a66f170d57b383b

See more details on using hashes here.

Provenance

The following attestation bundles were made for green_relay-0.1.0-py3-none-any.whl:

Publisher: python-client-publish.yml on Greenstorm5417/green_relay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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