Enterprise-ready Python SDK for Beem Africa APIs with focus on SMS and OTP functionality.
- β Connection Pooling - Reuse connections for better performance
- β
Health Check -
is_healthy()method for monitoring - β Exponential Backoff - Automatic retry with smart backoff
- β Comprehensive Error Handling - Detailed exception hierarchy
- β Full Type Hints - Complete mypy compliance
- β Configurable Logging - Built-in logging support
- β
Context Manager Support - Use with
withstatements - β Phone Number Validation - Automatic Tanzanian number formatting
pip install beem-africa-python-sdkfrom beem_africa_sdk import CompleteBeemClient
# For separate SMS and OTP credentials (recommended)
client = CompleteBeemClient(
api_key="your_sms_api_key", # SMS API key
secret_key="your_sms_secret_key", # SMS secret key
otp_api_key="your_otp_api_key", # OTP API key (separate)
otp_secret_key="your_otp_secret_key" # OTP secret key (separate)
)
# For same credentials (if your account uses same keys for both)
client = CompleteBeemClient(
api_key="your_api_key",
secret_key="your_secret_key"
# otp_api_key and otp_secret_key will default to api_key/secret_key
)
# Check API health
if client.is_healthy():
print("β
Beem API is accessible")
else:
print("β Beem API is unreachable")# Set approved sender IDs for your account
client.set_approved_senders(["INFO", "COMPANY", "ALERTS"])
# Add individual sender IDs
client.add_approved_sender("PROMO")
# Get list of approved senders
approved = client.get_approved_senders()
print(f"Approved senders: {approved}")
# Validate if a sender ID is approved (sends test SMS)
is_valid = client.validate_sender_id("INFO")
print(f"INFO is approved: {is_valid}")# Configure approved sender IDs
client.set_approved_senders(["INFO", "COMPANY"])
# Send SMS using default approved sender (INFO)
response = client.send_sms(
message="Your voucher code: ABC123XYZ",
recipients="255712345678"
)
# Send SMS with specific sender
response = client.send_sms(
message="Hello valued customers!",
recipients=["255712345678", "255798765432"],
source_addr="COMPANY"
)
print(f"Valid: {response['valid']}, Invalid: {response['invalid']}")Use the schedule_time parameter (UTC, format "yyyy-mm-dd hh:mm") to deliver a message at a future time.
from datetime import datetime, timezone, timedelta
# Schedule 2 hours from now
send_at = datetime.now(timezone.utc) + timedelta(hours=2)
schedule_time = send_at.strftime("%Y-%m-%d %H:%M")
# Single recipient
response = client.send_sms(
message="Your appointment reminder.",
recipients="255712345678",
source_addr="INFO",
schedule_time=schedule_time
)
print(f"Scheduled: {response['request_id']}")
# Multiple recipients
response = client.send_sms(
message="Team broadcast scheduled.",
recipients=["255712345678", "255798765432", "255754321098"],
source_addr="INFO",
schedule_time=schedule_time
)
print(f"Bulk scheduled: {response['request_id']}, Valid: {response['valid']}")Note: OTP functionality uses separate API credentials from SMS. Beem provides different API keys for SMS and OTP services. Use your OTP-specific credentials:
# Send OTP (using separate OTP credentials)
otp_data = client.send_otp("255712345678", app_id="your_app_id")
pin_id = otp_data['data']['pinId']
print(f"π± OTP sent! Pin ID: {pin_id}")
# Send OTP with custom sender ID
otp_data = client.send_otp(
phone="255712345678",
app_id="your_app_id",
sender_id="INFO"
)
pin_id = otp_data['data']['pinId']
print(f"π± OTP sent! Pin ID: {pin_id}")
# Later, verify OTP (user enters code)
user_code = input("Enter OTP code: ")
is_valid = client.verify_otp(pin_id, user_code)
if is_valid:
print("β
OTP verified successfully!")
else:
print("β Invalid OTP code")# Check SMS balance
balance = client.get_balance()
print(f"Current balance: {balance} SMS credits")
# Get delivery report (call after 5+ minutes)
reports = client.get_delivery_report(
dest_addr="255712345678",
request_id="your_request_id"
)
for report in reports:
print(f"Status: {report['status']}, Timestamp: {report['timestamp']}")# Automatic resource cleanup
with CompleteBeemClient("api_key", "secret_key") as client:
client.send_sms("SENDER", "Hello!", ["255712345678"])
# Client automatically closed hereThe SDK provides comprehensive error handling with specific exception types:
from beem_africa_sdk import CompleteBeemClient
from beem_africa_sdk.exceptions import (
BeemAuthenticationError,
BeemValidationError,
BeemInsufficientBalanceError,
BeemConnectionError
)
client = CompleteBeemClient("api_key", "secret_key")
try:
client.send_sms("SENDER", "Hello!", ["invalid_phone"])
except BeemValidationError as e:
print(f"Validation error: {e}")
except BeemAuthenticationError as e:
print(f"Authentication failed: {e}")
except BeemInsufficientBalanceError as e:
print(f"Insufficient balance: {e}")
except BeemConnectionError as e:
print(f"Connection error: {e}")Main client class with all functionality.
CompleteBeemClient(
api_key: str,
secret_key: str,
timeout: int = 30,
max_retries: int = 3,
pool_connections: int = 10,
pool_maxsize: int = 100,
logger: Optional[logging.Logger] = None
)is_healthy() -> bool- Check API accessibilitysend_sms(...) -> Dict[str, Any]- Send SMS messagesget_balance() -> float- Get SMS credit balanceget_delivery_report(...) -> List[Dict]- Get delivery statussend_otp(...) -> Dict[str, Any]- Send OTPverify_otp(...) -> bool- Verify OTP codeclose()- Close HTTP connections
The SDK automatically validates and formats Tanzanian phone numbers:
- Input formats accepted:
0712345678,255712345678,+255712345678 - Output format:
255712345678(12 digits, no spaces or special chars)
Set credentials via environment variables:
export BEEM_API_KEY="your_api_key"
export BEEM_SECRET_KEY="your_secret_key"Configure logging for debugging:
import logging
logging.basicConfig(level=logging.DEBUG)
client = CompleteBeemClient("api_key", "secret_key")
# All HTTP requests will be logged- Unicode Characters: Beem API does not support Unicode characters, emojis, or special symbols in SMS messages. Messages containing these will be rejected with an error.
- Plain Text Only: Use ASCII characters only for reliable delivery.
- Sender ID: Maximum 11 characters, alphanumeric only. Must be pre-approved by Beem.
- Account Dependent: OTP functionality requires separate activation in your Beem account.
- Setup Required: Visit Beem dashboard β OTP menu β API Setup to generate API keys and configure applications.
- Application ID: Each OTP request requires an
app_idthat corresponds to your Beem application. - Error Codes:
100: SMS sent successfully101: Failed to send SMS117: Valid PIN (verification successful)114: Incorrect PIN115: PIN timeout116: Attempts exceeded
- Timing: Delivery reports should be requested at least 5 minutes after sending SMS.
- Separate Endpoint: Uses different API endpoint (
dlrapi.beem.africa) than main SMS API.
git clone https://github.com/JAXPARROW/beem-africa-python-sdk.git
cd beem-africa-python-sdk
pip install -e ".[dev]"pytestpython -m build- Jackson Linus - Creator and maintainer
MIT License - see LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
- π Documentation
- π Issues
- π¬ Discussions