Catalog PyPI
PACKAGE EXPLORERView in registry

afromessage

PyPI

Python SDK for AfroMessage API to send SMS and OTP

Versions collected1
Direct dependencies2From release 0.1.4
Last observed20 Oct, 21:13 UTC

README

Version 0.1.4 documentation

AfroMessage Python SDK

A complete Python SDK for the AfroMessage SMS and OTP API.
This package makes it easy to send single SMS, bulk SMS, and handle OTP challenges with minimal setup.


🚀 Installation

Install the package via pip:

pip install afromessage

🔑 Quick Start

Create a .env file in your project root:

AFROMESSAGE_TOKEN=your_api_token_here

Then in Python:

import os
from dotenv import load_dotenv
from afromessage import AfroMessage
from afromessage.models.sms_models import SendSMSRequest, BulkSMSRequest
from afromessage.models.otp_models import SendOTPRequest, VerifyOTPRequest

# Load environment variables
load_dotenv()
token = os.getenv("AFROMESSAGE_TOKEN")

if not token:
    raise ValueError("⚠️ Set AFROMESSAGE_TOKEN in your .env file!")

# Initialize the SDK
sdk = AfroMessage(token=token)

# --- Single SMS ---
sms_request = SendSMSRequest(
    to="+2519xxxxxxx",
    message="Hello from AfroMessage SDK!",
    from_="MySender",
    sender="MyBrand"
)
response = sdk.sms.send(sms_request)
print("✅ Single SMS:", response)

# --- Bulk SMS ---
bulk_request = BulkSMSRequest(
    to=["+2519xxxxxxx", "+2519yyyyyyy"],
    message="Hello, bulk users!",
    from_="MySender",
    sender="MyBrand",
    campaign="MyCampaign"
)
bulk_response = sdk.sms.bulk_send(bulk_request)
print("✅ Bulk SMS:", bulk_response)

#---  Personalized Bulk request ---

personalized_request = BulkSMSRequest(
    to=[
        BulkRecipient(to="+2519xxxxxxx", message="Hi Yonas!"),
        BulkRecipient(to="+2519yyyyyyy", message="Hi Eshetu!")
    ],
    from_="MySender",
    sender="MyBrand",
    campaign="PersonalizedCampaign"
)

response = sdk.sms.bulk_send(personalized_request)



# --- OTP Challenge ---
otp_request = SendOTPRequest(
    to="+2519xxxxxxx",
    pr="Your code",
    len_=6
)
otp_response = sdk.otp.send(otp_request)
print("✅ OTP Challenge:", otp_response)

# --- Verify OTP ---
verify_request = VerifyOTPRequest(
    to="+2519xxxxxxx",
    code="123456"
)
verify_response = sdk.otp.verify(verify_request)
print("✅ OTP Verify:", verify_response)

📦 Features

✅ Send single SMS

✅ Send bulk SMS campaigns

✅ Generate OTP challenges

✅ Verify OTP codes

✅ Built-in error handling

✅ Request/response logging for debugging

⚡ API Reference

Single SMS

from afromessage.models.sms_models import SendSMSRequest

sms_request = SendSMSRequest(
    to="+2519xxxxxxx",
    message="Hello from AfroMessage!",
    from_="MySender",
    sender="MyBrand",
    callback="https://myapp.com/callback"  # optional
)

response = sdk.sms.send(sms_request)

Single SMS (GET request)

response = sdk.sms.send_get(sms_request)

Bulk SMS

from afromessage.models.sms_models import BulkSMSRequest

bulk_request = BulkSMSRequest(
    to=["+2519xxxxxxx", "+2519yyyyyyy"],
    message="Hello, everyone!",
    from_="MySender",
    sender="MyBrand",
    campaign="MyCampaign"
)

response = sdk.sms.bulk_send(bulk_request)

Bulk SMS (Personalized messages)

from afromessage.models.sms_models import BulkRecipient, BulkSMSRequest

personalized_request = BulkSMSRequest(
    to=[
        BulkRecipient(to="+2519xxxxxxx", message="Hi Yonas!"),
        BulkRecipient(to="+2519yyyyyyy", message="Hi Eshetu!")
    ],
    from_="MySender",
    sender="MyBrand",
    campaign="PersonalizedCampaign"
)

response = sdk.sms.bulk_send(personalized_request)

OTP Challenge

from afromessage.models.otp_models import SendOTPRequest

otp_request = SendOTPRequest(
    to="+2519xxxxxxx",
    pr="Your code",
    len_=6,
    ttl=300  # time-to-live in seconds (optional)
)

response = sdk.otp.send(otp_request)

Verify OTP

from afromessage.models.otp_models import VerifyOTPRequest

verify_request = VerifyOTPRequest(
    to="+2519xxxxxxx",
    code="123456"
)

response = sdk.otp.verify(verify_request)

🛠 Error Handling

All errors are wrapped and logged automatically.

Example:

try:
    response = sdk.sms.send(sms_request)
    print("✅ Success:", response)
except Exception as e:
    print("❌ Error:", str(e))

Errors include:

API errors (invalid request, authentication failure, etc.)

Network errors (timeouts, connection issues)

📑 Logging

Requests and responses are logged automatically. Example:

📤 [POST] Request to: send
   Payload: {
     "to": "+2519xxxxxxx",
     "message": "Hello!"
   }

📥 Response from: send
   Data: {
     "acknowledge": "success",
     "response": { "code": "202", "to": "+2519xxxxxxx" }
   }

🧪 Advanced Example (Real Test)

We provide a full interactive test script in usag/test_real.py

.

It shows how to send SMS, bulk SMS, and run OTP challenge + verification with .env loading.

Run it with:

python usage/test_real.py

⚠️ Note: Running this will send real SMS/OTP messages and may incur costs.

🤝 Contributing

Contributions are welcome! To contribute:

1. Fork the repo

2. Create your feature branch (git checkout -b feature/my-feature)

3. Commit your changes (git commit -m 'Add my feature')

4. Push to the branch (git push origin feature/my-feature)

5. Open a Pull Request

Run tests before submitting:

pytest

📜 License

This project is licensed under the MIT License.

See LICENSE

for details.

🙋 Support

For issues or feature requests, open a GitHub Issue

Downloads & popularity

1downloads
1-day window · source-reported counts16 Oct 2026
26130
2026-07-21: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-07-21–2026-07-212026-07-23: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-07-23–2026-07-232026-07-24: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-07-24–2026-07-242026-07-27: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-07-27–2026-07-272026-07-30: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-07-30–2026-07-302026-08-01: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-01–2026-08-012026-08-02: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-02–2026-08-022026-08-03: 6 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-03–2026-08-032026-08-09: 3 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-09–2026-08-092026-08-13: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-13–2026-08-132026-08-14: 4 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-14–2026-08-142026-08-17: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-17–2026-08-172026-08-20: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-20–2026-08-202026-08-21: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-21–2026-08-212026-08-23: 3 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-23–2026-08-232026-08-24: 6 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-24–2026-08-242026-08-28: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-08-31–2026-08-312026-09-01: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-01–2026-09-012026-09-02: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-02–2026-09-022026-09-07: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-07–2026-09-072026-09-09: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-09–2026-09-092026-09-12: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-12–2026-09-122026-09-14: 6 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-14–2026-09-142026-09-16: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-16–2026-09-162026-09-18: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-18–2026-09-182026-09-20: 6 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-20–2026-09-202026-09-24: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-24–2026-09-242026-09-25: 12 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-25–2026-09-252026-09-26: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-26–2026-09-262026-09-27: 2 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-27–2026-09-272026-09-28: 3 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-28–2026-09-282026-09-29: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-29–2026-09-292026-09-30: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-09-30–2026-09-302026-10-02: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-02–2026-10-022026-10-06: 3 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-06–2026-10-062026-10-07: 5 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-07–2026-10-072026-10-08: 5 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-08–2026-10-082026-10-09: 8 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-09–2026-10-092026-10-10: 26 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-10–2026-10-102026-10-11: 10 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-11–2026-10-112026-10-12: 14 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-12–2026-10-122026-10-13: 7 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-13–2026-10-132026-10-15: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-15–2026-10-152026-10-16: 1 · observed 2026-10-20T21:28:13.9256312Z · period 2026-10-16–2026-10-16
21 Jul16 Oct

pypistats · 45 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-16 – 2026-10-1612026-10-20T21:28:13.9256312Z
2026-10-15 – 2026-10-1512026-10-20T21:28:13.9256312Z
2026-10-13 – 2026-10-1372026-10-20T21:28:13.9256312Z
2026-10-12 – 2026-10-12142026-10-20T21:28:13.9256312Z
2026-10-11 – 2026-10-11102026-10-20T21:28:13.9256312Z
2026-10-10 – 2026-10-10262026-10-20T21:28:13.9256312Z
2026-10-09 – 2026-10-0982026-10-20T21:28:13.9256312Z
2026-10-08 – 2026-10-0852026-10-20T21:28:13.9256312Z
2026-10-07 – 2026-10-0752026-10-20T21:28:13.9256312Z
2026-10-06 – 2026-10-0632026-10-20T21:28:13.9256312Z
2026-10-02 – 2026-10-0212026-10-20T21:28:13.9256312Z
2026-09-30 – 2026-09-3012026-10-20T21:28:13.9256312Z
2026-09-29 – 2026-09-2912026-10-20T21:28:13.9256312Z
2026-09-28 – 2026-09-2832026-10-20T21:28:13.9256312Z
2026-09-27 – 2026-09-2722026-10-20T21:28:13.9256312Z
2026-09-26 – 2026-09-2612026-10-20T21:28:13.9256312Z
2026-09-25 – 2026-09-25122026-10-20T21:28:13.9256312Z
2026-09-24 – 2026-09-2412026-10-20T21:28:13.9256312Z
2026-09-20 – 2026-09-2062026-10-20T21:28:13.9256312Z
2026-09-18 – 2026-09-1822026-10-20T21:28:13.9256312Z
2026-09-16 – 2026-09-1612026-10-20T21:28:13.9256312Z
2026-09-14 – 2026-09-1462026-10-20T21:28:13.9256312Z
2026-09-12 – 2026-09-1212026-10-20T21:28:13.9256312Z
2026-09-09 – 2026-09-0912026-10-20T21:28:13.9256312Z
2026-09-07 – 2026-09-0712026-10-20T21:28:13.9256312Z
2026-09-02 – 2026-09-0212026-10-20T21:28:13.9256312Z
2026-09-01 – 2026-09-0122026-10-20T21:28:13.9256312Z
2026-08-31 – 2026-08-3122026-10-20T21:28:13.9256312Z
2026-08-28 – 2026-08-2822026-10-20T21:28:13.9256312Z
2026-08-24 – 2026-08-2462026-10-20T21:28:13.9256312Z
2026-08-23 – 2026-08-2332026-10-20T21:28:13.9256312Z
2026-08-21 – 2026-08-2112026-10-20T21:28:13.9256312Z
2026-08-20 – 2026-08-2012026-10-20T21:28:13.9256312Z
2026-08-17 – 2026-08-1722026-10-20T21:28:13.9256312Z
2026-08-14 – 2026-08-1442026-10-20T21:28:13.9256312Z
2026-08-13 – 2026-08-1322026-10-20T21:28:13.9256312Z
2026-08-09 – 2026-08-0932026-10-20T21:28:13.9256312Z
2026-08-03 – 2026-08-0362026-10-20T21:28:13.9256312Z
2026-08-02 – 2026-08-0222026-10-20T21:28:13.9256312Z
2026-08-01 – 2026-08-0112026-10-20T21:28:13.9256312Z
2026-07-30 – 2026-07-3012026-10-20T21:28:13.9256312Z
2026-07-27 – 2026-07-2722026-10-20T21:28:13.9256312Z
2026-07-24 – 2026-07-2412026-10-20T21:28:13.9256312Z
2026-07-23 – 2026-07-2322026-10-20T21:28:13.9256312Z
2026-07-21 – 2026-07-2112026-10-20T21:28:13.9256312Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.424 Sept 20252

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
yonas8989/afromessage-python-sdk

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:13 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:24b28107210d70b884ba767ee72efa01fc09356dd73ee8faf8e144137f695848