Skip to main content

Python SDK

License: MIT PyPI version

A Python SDK for integrating with Notify Africa SMS service, allowing developers to easily send SMS messages through their Python applications. This SDK aligns with the Node.js SDK structure for consistency.

Features

  • Send Single SMS
  • Send Batch SMS
  • Check Message Status
  • Developer-friendly: type hints, structured errors, clear models
  • Compatible structure with the Node.js SDK

Installation

pip install notify-africa

Optional: upgrade to the latest version

pip install -U notify-africa

Quick Start

from notify_africa import NotifyAfrica

# Initialize client
client = NotifyAfrica(apiToken="your_api_token_here")

# Send a single SMS
response = client.send_single_message(
phoneNumber="2556XXXXXXXX",
message="Hello from Notify Africa!",
senderId="164",
)

print(f"Message ID: {response.messageId}")
print(f"Status: {response.status}")

Configuration

  • API token: recommended to store in an environment variable and pass to the constructor.
  • Base URL: optional override for staging/regional environments.
# export NOTIFY_AFRICA_API_TOKEN="ntfy_..."
import os
from notify_africa import NotifyAfrica

client = NotifyAfrica(apiToken=os.getenv("NOTIFY_AFRICA_API_TOKEN"), baseUrl="https://api.notify.africa")

Usage Examples

Send Single SMS

from notify_africa import NotifyAfrica

client = NotifyAfrica(apiToken="your_api_token")

response = client.send_single_message(
phoneNumber="2556XXXXXXXXX",
message="Hello, this is a test message!",
senderId="164",
)

print(f"Message ID: {response.messageId}")
print(f"Status: {response.status}")
# Output: Message ID: 165102
# Output: Status: PROCESSING

Send Batch SMS

from notify_africa import NotifyAfrica

client = NotifyAfrica(apiToken="your_api_token")

phone_numbers = [
"2556XXXXXXXXXX",
"255XXXXXXXX",
"255XXXXXXXX",
]

response = client.send_batch_messages(
phoneNumbers=phone_numbers,
message="Bulk SMS message to all recipients",
senderId="164",
)

print(f"Message Count: {response.messageCount}")
print(f"Credits Deducted: {response.creditsDeducted}")
print(f"Remaining Balance: {response.remainingBalance}")

Check Message Status

from notify_africa import NotifyAfrica

client = NotifyAfrica(apiToken="your_api_token")

# First, send a message
send_response = client.send_single_message(
phoneNumber="2556XXXXXXX",
message="Test message",
senderId="164",
)

message_id = send_response.messageId

# Then check its status
status = client.check_message_status(messageId=message_id)

print(f"Message ID: {status.messageId}")
print(f"Status: {status.status}")
print(f"Sent At: {status.sentAt}")
print(f"Delivered At: {status.deliveredAt}")

API Reference

NotifyAfrica Class

Constructor

NotifyAfrica(apiToken: str, baseUrl: str = "https://api.notify.africa")

Parameters:

  • apiToken (str, required): Your Notify Africa API token.
  • baseUrl (str, optional): Base URL for the API (default: https://api.notify.africa).

Example:

client = NotifyAfrica(apiToken="ntfy_...")

Methods

send_single_message

Sends a single SMS message.

send_single_message(
phoneNumber: str,
message: str,
senderId: str,
) -> SendSingleResponse

Parameters:

  • phoneNumber (str): Recipient phone number in international format.
  • message (str): Message content.
  • senderId (str): Sender ID.

Returns: SendSingleResponse with messageId: str, status: str.

send_batch_messages

Sends a batch of SMS messages to multiple recipients.

send_batch_messages(
phoneNumbers: list[str],
message: str,
senderId: str,
) -> SendBatchResponse

Returns: SendBatchResponse with messageCount: int, creditsDeducted: int, remainingBalance: int.

check_message_status

Checks the status of a sent message.

check_message_status(messageId: str) -> MessageStatusResponse

Returns: MessageStatusResponse with messageId: str, status: str, sentAt: str | None, deliveredAt: str | None.

Response Models

SendSingleResponse

from dataclasses import dataclass

@dataclass
class SendSingleResponse:
messageId: str
status: str

SendBatchResponse

from dataclasses import dataclass

@dataclass
class SendBatchResponse:
messageCount: int
creditsDeducted: int
remainingBalance: int

MessageStatusResponse

from dataclasses import dataclass

@dataclass
class MessageStatusResponse:
messageId: str
status: str
sentAt: str | None
deliveredAt: str | None

Error Handling

The SDK raises structured exceptions for common failure modes:

from notify_africa import NotifyAfrica
from notify_africa.exceptions import (
NotifyAfricaException,
NetworkError,
AuthenticationError,
ValidationError,
InsufficientCreditsError,
)

client = NotifyAfrica(apiToken="your_api_token")

try:
response = client.send_single_message(
phoneNumber="2556XXXXXXX",
message="Test message",
senderId="164",
)
print(f"Success! Message ID: {response.messageId}")
except AuthenticationError:
print("Authentication failed. Check your API token.")
except InsufficientCreditsError:
print("Insufficient credits. Please recharge your account.")
except ValidationError as e:
print(f"Validation error: {e}")
except NetworkError as e:
print(f"Network error: {e}")
except NotifyAfricaException as e:
print(f"API error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")

Advanced Usage

Complete Workflow Example

from notify_africa import NotifyAfrica
from notify_africa.exceptions import NotifyAfricaException, NetworkError


def send_and_track_sms(client, phone_number, message, sender_id):
"""Send SMS and track its delivery status"""
try:
# Send the message
send_response = client.send_single_message(
phoneNumber=phone_number,
message=message,
senderId=sender_id,
)
print(f"Message sent! ID: {send_response.messageId}")
print(f"Initial status: {send_response.status}")

# Wait briefly for processing
import time
time.sleep(2)

# Check status
status = client.check_message_status(send_response.messageId)
print(f"Current status: {status.status}")
if status.sentAt:
print(f"Sent at: {status.sentAt}")
if status.deliveredAt:
print(f"Delivered at: {status.deliveredAt}")
return status
except (NotifyAfricaException, NetworkError) as e:
print(f"Error: {e}")
return None


# Usage
client = NotifyAfrica(apiToken="your_api_token")
send_and_track_sms(
client=client,
phone_number="2556XXXXXXXX",
message="Hello from Python SDK!",
sender_id="164",
)

Batch Processing with Status Tracking

from notify_africa import NotifyAfrica


def send_batch_and_track(client, phone_numbers, message, sender_id):
"""Send batch messages and log the summary"""
# Send batch
batch_response = client.send_batch_messages(
phoneNumbers=phone_numbers,
message=message,
senderId=sender_id,
)

print(f"Batch sent: {batch_response.messageCount} messages")
print(f"Credits deducted: {batch_response.creditsDeducted}")
print(f"Remaining balance: {batch_response.remainingBalance}")
return batch_response


# Usage
client = NotifyAfrica(apiToken="your_api_token")
send_batch_and_track(
client=client,
phone_numbers=["255XXXXX", "255XXXXXX"],
message="Batch test message",
sender_id="164",
)

SMS Status Codes

Status CodeDescription
PROCESSINGSMS is being processed
QUEUEDSMS is queued for delivery
SENTSMS has been sent to carrier
DELIVEREDSMS was successfully delivered
FAILEDSMS delivery failed
EXPIREDSMS expired before delivery
REJECTEDSMS was rejected by carrier

Environment Variables

You can store your API token in an environment variable for convenience:

export NOTIFY_AFRICA_API_TOKEN="your_api_token_here"

Then in Python:

import os
from notify_africa import NotifyAfrica

client = NotifyAfrica(apiToken=os.getenv("NOTIFY_AFRICA_API_TOKEN"))

Troubleshooting

  • Ensure your API token is valid and passed to the client.
  • Phone numbers must be in international format (e.g., 255...).
  • If you receive PROCESSING status, poll the status endpoint to track delivery.
  • Network/proxy issues: verify your environment can reach https://api.notify.africa.

Requirements

  • Python 3.7+
  • requests library

License

MIT License. See LICENSE in the repository.

Support

Changelog

1.0.0

  • Initial release matching Node.js SDK structure
  • Support for single/batch SMS
  • Message status checking
  • Comprehensive error handling