KiboNet Python SDK
Simple, secure Python SDK for the KiboNet SMS Gateway.
Supports both synchronous and async usage via httpx.
Features
- Send SMS to one or multiple recipients (comma-separated contacts)
- Delivery reports retrieved by
shootId - Balance check for your SMS credits
- Health check —
is_healthy()never raises, perfect for monitoring probes - Async support — full
async/awaitviaAsyncKiboNetClient - httpx under the hood — connection pooling, automatic retries, TLS verification
- Phone number validation — auto-converts
0XXXXXXXXX→255XXXXXXXXX - Typed exceptions — catch exactly what you need
- Context manager support (both sync and async)
- No credentials in code — load from environment variables
Installation
pip install kibonet-python-sdk
Quick Start
Synchronous
from kibonet_sdk import KiboNetClient
with KiboNetClient(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET") as client:
# Health check
if client.is_healthy():
print("API is up!")
# Send SMS
resp = client.send_sms(
sender_id="MyBrand",
message="Hello from KiboNet!",
contacts=["255712345678", "255798765432"],
delivery_report_url="https://myserver.com/delivery-callback", # optional
)
print(f"Shoot ID: {resp['data']['shootId']}")
print(f"Valid: {resp['data']['validContacts']}")
Asynchronous
import asyncio
from kibonet_sdk import AsyncKiboNetClient
async def main():
async with AsyncKiboNetClient(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET") as client:
if await client.is_healthy():
resp = await client.send_sms(
sender_id="MyBrand",
message="Hello async!",
contacts="255712345678",
)
print(resp["data"]["shootId"])
asyncio.run(main())
All Methods
Both KiboNetClient and AsyncKiboNetClient expose the same interface:
send_sms
resp = client.send_sms(
sender_id="MyBrand", # Sender name shown to recipient
message="Your OTP is 1234", # SMS text
contacts=[ # Single string, list, or CSV string
"255712345678",
"255798765432",
],
delivery_report_url="https://myserver.com/callback", # optional
message_type="text", # currently only "text" is supported
)
# Response
print(resp["data"]["shootId"]) # Use this for delivery reports
print(resp["data"]["validContacts"]) # int
print(resp["data"]["invalidContacts"]) # int
print(resp["data"]["duplicatedContacts"])
print(resp["data"]["messageSize"]) # character count
get_delivery_report
report = client.get_delivery_report("abcd1234-5678-efgh-9012-ijklmnopqrst")
for record in report["data"]:
print(record["mobile"]) # 255712345678
print(record["status"]) # Delivered / Failed / Buffered
print(record["statusCode"]) # 000
print(record["sentAt"]) # "07-02-2024 07:35:08"
get_balance
result = client.get_balance()
print(result["data"]["totalSms"]) # e.g. 30
is_healthy
if client.is_healthy():
print("API is reachable and credentials are valid")
Phone Number Formats
The SDK automatically normalises phone numbers:
| Input format | Stored as |
|---|---|
0712345678 |
255712345678 |
+255712345678 |
255712345678 |
255712345678 |
255712345678 |
Error Handling
from kibonet_sdk import KiboNetClient
from kibonet_sdk.exceptions import (
KiboNetAuthenticationError,
KiboNetValidationError,
KiboNetRateLimitError,
KiboNetInsufficientBalanceError,
KiboNetConnectionError,
KiboNetServerError,
KiboNetAPIError,
KiboNetError, # base — catch everything SDK-related
)
client = KiboNetClient(api_key="...", api_secret="...")
try:
client.send_sms(sender_id="X", message="Hi", contacts="255712345678")
except KiboNetAuthenticationError:
print("Bad credentials")
except KiboNetValidationError as e:
print(f"Input error: {e}")
except KiboNetRateLimitError:
print("Slow down — rate limited")
except KiboNetConnectionError as e:
print(f"Network error: {e}")
except KiboNetServerError as e:
print(f"KiboNet server problem: {e}")
except KiboNetAPIError as e:
print(f"API error (code={e.code}): {e}")
Environment Variables
Keep credentials out of source code:
export KIBONET_API_KEY="your_api_key"
export KIBONET_API_SECRET="your_api_secret"
import os
from kibonet_sdk import KiboNetClient
client = KiboNetClient(
api_key=os.environ["KIBONET_API_KEY"],
api_secret=os.environ["KIBONET_API_SECRET"],
)
Constructor Options
KiboNetClient(
api_key: str, # Required — from KiboNet portal
api_secret: str, # Required — from KiboNet portal
timeout: float = 30.0, # Per-request timeout in seconds
max_retries: int = 3, # Automatic retries on transient failures
logger=None, # Optional logging.Logger
)
AsyncKiboNetClient takes the same parameters.
Logging
import logging
logging.basicConfig(level=logging.DEBUG)
client = KiboNetClient(api_key="...", api_secret="...")
# All HTTP calls are logged at DEBUG level
Development
git clone https://github.com/JAXPARROW/kibonet-python-sdk.git
cd kibonet-python-sdk
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=kibonet_sdk --cov-report=term-missing
# Build
python -m build
License
MIT — see LICENSE.
Contributors
- Jackson Linus — Creator and maintainer
Metadata
Release files for kibonet-python-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kibonet_python_sdk-0.1.0.tar.gz | 12.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kibonet_python_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.7 kB
Release files / kibonet_python_sdk-0.1.0.tar.gz
| Download URL | kibonet_python_sdk-0.1.0.tar.gz |
|---|---|
| Size | 12.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c910173d835655ee0aae437ea42fb0bcfa0373c5478f9bdc0dfdb4476aee627c
|
|
BLAKE2b-256 checksum How to use checksums |
696611375ed299ae8420121c3418b121ad6cf8c9056d5e58def37bdc1fedd43d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / kibonet_python_sdk-0.1.0-py3-none-any.whl
| Download URL | kibonet_python_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ce3afb30be3ddadc5e7d68b5f40d9417f5dacd88dc871ebf9a05c3f35fc11ff
|
|
BLAKE2b-256 checksum How to use checksums |
aa7b931fa7df00ab940143da46ee459adf680e3c3de9c813940f53d13f025520
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|