notify-africa-sms


Namenotify-africa-sms JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/notify-africa/python-sdk
SummaryPython SDK for Notify Africa SMS Service
upload_time2025-07-15 14:53:25
maintainerNone
docs_urlNone
authorNotify Africa
requires_python>=3.7
licenseNone
keywords sms tanzania api sdk notify-africa
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Notify Africa Python SMS SDK

A Python SDK for integrating with Notify Africa SMS service, allowing developers to easily send SMS messages through their Python applications.

## Features

- ✅ **Authentication** - API key and sender ID management
- 📤 **Send Single SMS** - Send SMS to individual recipients
- 📦 **Send Bulk SMS** - Send SMS to multiple recipients
- 🕒 **Send Scheduled SMS** - Schedule SMS for future delivery
- 📁 **Excel Integration** - Send SMS from Excel files
- 📊 **Delivery Reports** - Check SMS delivery status
- 🛠️ **Developer Friendly** - Type hints, error handling, and comprehensive documentation

## Installation

```bash
pip install notify-africa-sms
```

## Quick Start

```python
from notify_africa import NotifyAfricaClient

# Initialize client
client = NotifyAfricaClient(
    api_key="your_api_key_here",
    sender_id="NOTIFYAFRICA"
)

# Send a single SMS
response = client.send_sms(
    phone_number="255712345678",
    message="Hello from Notify Africa!"
)

print(f"SMS sent: {response.success}")
print(f"Message: {response.message}")
print(f"Balance: {response.balance}")
```

## Usage Examples

### Send Single SMS

```python
response = client.send_sms(
    phone_number="255712345678", 
    message="Hello, this is a test message!"
)

if response.success:
    print(f"SMS sent successfully! ID: {response.sms_id}")
    print(f"Credits used: {response.credits_spent}")
    print(f"Remaining balance: {response.balance}")
else:
    print(f"Failed to send SMS: {response.message}")
```

### Send Bulk SMS

```python
phone_numbers = [
    "255712345678",
    "255687654321", 
    "255756789012"
]

response = client.send_bulk_sms(
    phone_numbers=phone_numbers,
    message="Bulk SMS message to all recipients"
)

print(f"Total messages: {response.total_messages}")
print(f"Successful: {response.successful_messages}")
print(f"Failed: {response.failed_messages}")
```

### Send Scheduled SMS

```python
from datetime import datetime, timedelta

# Schedule SMS for tomorrow at 10:00 AM
schedule_time = datetime.now() + timedelta(days=1)
schedule_time = schedule_time.replace(hour=10, minute=0, second=0)

response = client.send_scheduled_sms(
    phone_numbers=["255712345678"],
    message="This is a scheduled message",
    schedule_time=schedule_time
)

print(f"Scheduled SMS: {response.success}")
```

### Send SMS from Excel File

Create an Excel file with columns: `phone`, `names`, `message` (optional)

```python
# Using message template with name placeholder
response = client.send_sms_from_excel(
    file_path="contacts.xlsx",
    message_template="Hello {names}, welcome to our service!",
    phone_column="phone",
    names_column="names"
)

# Or using individual messages from Excel
response = client.send_sms_from_excel(
    file_path="contacts.xlsx",
    message_column="message",
    phone_column="phone"
)

print(f"Sent {response.successful_messages} out of {response.total_messages} SMS")
```

### Check SMS History

```python
history = client.get_sms_history(records=50)
print(f"Retrieved {len(history.get('data', []))} SMS records")
```

### Get Sender IDs

```python
sender_ids = client.get_sender_ids()
for sender in sender_ids:
    print(f"Sender ID: {sender.name} - Status: {sender.status}")
```

## SMS Status and History Tracking

The Notify Africa Python SDK provides comprehensive methods to track SMS delivery status and retrieve SMS history.

### Check SMS History

Retrieve your SMS sending history with detailed information about each message:

```python
# Get recent SMS history (default: 50 records)
history = client.get_sms_history()

# Get specific number of records
history = client.get_sms_history(records=100)

# Process the history data
messages = history.get('data', [])
print(f"Total messages retrieved: {len(messages)}")

for message in messages:
    print(f"SMS ID: {message.get('id')}")
    print(f"Recipient: {message.get('recipient')}")
    print(f"Message: {message.get('sms')}")
    print(f"Status: {message.get('status_id')}")
    print(f"Status Description: {message.get('status_description')}")
    print(f"Credits Used: {message.get('credits')}")
    print(f"Sent At: {message.get('created_at')}")
    print(f"Sender ID: {message.get('sender_id')}")
    print("-" * 40)
```

### Check Individual SMS Status

Check the delivery status of a specific SMS using its ID:

```python
# Get SMS ID from send response
response = client.send_sms("255712345678", "Test message")
sms_id = response.sms_id

# Check delivery status
status = client.get_delivery_status(sms_id)

if status:
    print(f"SMS ID: {status.sms_id}")
    print(f"Recipient: {status.recipient}")
    print(f"Status: {status.status}")
    print(f"Description: {status.status_description}")
    print(f"Credits: {status.credits}")
else:
    print("SMS not found or status unavailable")
```

### SMS Status Codes

The following status codes are commonly returned:

| Status Code | Description |
|-------------|-------------|
| `pending` | SMS is queued for delivery |
| `sent` | SMS has been sent to the carrier |
| `delivered` | SMS was successfully delivered |
| `failed` | SMS delivery failed |
| `expired` | SMS expired before delivery |
| `rejected` | SMS was rejected by the carrier |

### Advanced History Filtering

```python
# Get comprehensive SMS history with filtering
def get_filtered_sms_history(client, days_back=7, status_filter=None):
    """
    Get filtered SMS history
    
    Args:
        client: NotifyAfricaClient instance
        days_back: Number of days to look back
        status_filter: Filter by specific status (optional)
    """
    from datetime import datetime, timedelta
    
    # Get recent history (API typically returns newest first)
    history = client.get_sms_history(records=500)
    messages = history.get('data', [])
    
    # Filter by date range
    cutoff_date = datetime.now() - timedelta(days=days_back)
    filtered_messages = []
    
    for msg in messages:
        try:
            # Parse message date
            msg_date = datetime.fromisoformat(
                msg.get('created_at', '').replace('Z', '+00:00')
            )
            
            # Check if within date range
            if msg_date >= cutoff_date:
                # Apply status filter if specified
                if status_filter is None or msg.get('status_id') == status_filter:
                    filtered_messages.append(msg)
        except:
            continue
    
    return filtered_messages

# Usage examples
recent_messages = get_filtered_sms_history(client, days_back=7)
failed_messages = get_filtered_sms_history(client, days_back=30, status_filter='failed')
delivered_messages = get_filtered_sms_history(client, days_back=7, status_filter='delivered')

print(f"Recent messages (7 days): {len(recent_messages)}")
print(f"Failed messages (30 days): {len(failed_messages)}")
print(f"Delivered messages (7 days): {len(delivered_messages)}")
```

### Bulk Status Checking

Check status for multiple SMS messages:

```python
def check_bulk_sms_status(client, sms_ids):
    """
    Check status for multiple SMS messages
    
    Args:
        client: NotifyAfricaClient instance
        sms_ids: List of SMS IDs to check
    """
    results = []
    
    for sms_id in sms_ids:
        status = client.get_delivery_status(sms_id)
        if status:
            results.append({
                'sms_id': status.sms_id,
                'recipient': status.recipient,
                'status': status.status,
                'description': status.status_description
            })
        else:
            results.append({
                'sms_id': sms_id,
                'status': 'not_found',
                'description': 'SMS not found in history'
            })
    
    return results

# Usage
sms_ids = ['123', '124', '125']  # Your SMS IDs
statuses = check_bulk_sms_status(client, sms_ids)

for status in statuses:
    print(f"SMS {status['sms_id']}: {status['status']} - {status['description']}")
```

### Real-time Status Monitoring

Monitor SMS delivery in real-time:

```python
import time
from datetime import datetime

def monitor_sms_delivery(client, sms_id, timeout=300):
    """
    Monitor SMS delivery status until delivered or timeout
    
    Args:
        client: NotifyAfricaClient instance
        sms_id: SMS ID to monitor
        timeout: Maximum time to wait in seconds (default: 5 minutes)
    """
    start_time = time.time()
    
    while time.time() - start_time < timeout:
        status = client.get_delivery_status(sms_id)
        
        if status:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] SMS {sms_id}: {status.status}")
            
            # Check if final status reached
            if status.status in ['delivered', 'failed', 'expired', 'rejected']:
                return status
        
        time.sleep(10)  # Wait 10 seconds before checking again
    
    print(f"Timeout reached for SMS {sms_id}")
    return None

# Usage
response = client.send_sms("255712345678", "Test message")
if response.success:
    final_status = monitor_sms_delivery(client, response.sms_id)
    if final_status:
        print(f"Final status: {final_status.status}")
```

### Export SMS History

Export SMS history to different formats:

```python
import pandas as pd
from datetime import datetime

def export_sms_history(client, records=1000, format='csv'):
    """
    Export SMS history to file
    
    Args:
        client: NotifyAfricaClient instance
        records: Number of records to export
        format: Export format ('csv', 'excel', 'json')
    """
    # Get SMS history
    history = client.get_sms_history(records=records)
    messages = history.get('data', [])
    
    if not messages:
        print("No SMS history found")
        return
    
    # Create DataFrame
    df = pd.DataFrame(messages)
    
    # Generate filename with timestamp
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    
    if format.lower() == 'csv':
        filename = f"sms_history_{timestamp}.csv"
        df.to_csv(filename, index=False)
    elif format.lower() == 'excel':
        filename = f"sms_history_{timestamp}.xlsx"
        df.to_excel(filename, index=False)
    elif format.lower() == 'json':
        filename = f"sms_history_{timestamp}.json"
        df.to_json(filename, orient='records', indent=2)
    
    print(f"SMS history exported to: {filename}")
    return filename

# Usage
export_sms_history(client, records=500, format='excel')
```

### Error Handling for Status Checks

```python
from notify_africa.exceptions import (
    AuthenticationError,
    NetworkError,
    NotifyAfricaException
)

def safe_status_check(client, sms_id):
    """Safely check SMS status with error handling"""
    try:
        status = client.get_delivery_status(sms_id)
        return status
    except AuthenticationError:
        print("Authentication failed - check your API key")
        return None
    except NetworkError as e:
        print(f"Network error: {e}")
        return None
    except NotifyAfricaException as e:
        print(f"API error: {e}")
        return None
    except Exception as e:
        print(f"Unexpected error: {e}")
        return None

def safe_history_check(client, records=50):
    """Safely get SMS history with error handling"""
    try:
        history = client.get_sms_history(records=records)
        return history.get('data', [])
    except AuthenticationError:
        print("Authentication failed - check your API key")
        return []
    except NetworkError as e:
        print(f"Network error: {e}")
        return []
    except NotifyAfricaException as e:
        print(f"API error: {e}")
        return []
    except Exception as e:
        print(f"Unexpected error: {e}")
        return []

# Usage
status = safe_status_check(client, "123")
messages = safe_history_check(client, 100)
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/notify-africa/python-sdk",
    "name": "notify-africa-sms",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "sms, tanzania, api, sdk, notify-africa",
    "author": "Notify Africa",
    "author_email": "support@notifyafrica.com",
    "download_url": "https://files.pythonhosted.org/packages/8a/c8/f7947118c1f83e4cfc604ea52d4dc85bd555d836f9d12e6a9316f7739630/notify_africa_sms-1.0.0.tar.gz",
    "platform": null,
    "description": "# Notify Africa Python SMS SDK\n\nA Python SDK for integrating with Notify Africa SMS service, allowing developers to easily send SMS messages through their Python applications.\n\n## Features\n\n- \u2705 **Authentication** - API key and sender ID management\n- \ud83d\udce4 **Send Single SMS** - Send SMS to individual recipients\n- \ud83d\udce6 **Send Bulk SMS** - Send SMS to multiple recipients\n- \ud83d\udd52 **Send Scheduled SMS** - Schedule SMS for future delivery\n- \ud83d\udcc1 **Excel Integration** - Send SMS from Excel files\n- \ud83d\udcca **Delivery Reports** - Check SMS delivery status\n- \ud83d\udee0\ufe0f **Developer Friendly** - Type hints, error handling, and comprehensive documentation\n\n## Installation\n\n```bash\npip install notify-africa-sms\n```\n\n## Quick Start\n\n```python\nfrom notify_africa import NotifyAfricaClient\n\n# Initialize client\nclient = NotifyAfricaClient(\n    api_key=\"your_api_key_here\",\n    sender_id=\"NOTIFYAFRICA\"\n)\n\n# Send a single SMS\nresponse = client.send_sms(\n    phone_number=\"255712345678\",\n    message=\"Hello from Notify Africa!\"\n)\n\nprint(f\"SMS sent: {response.success}\")\nprint(f\"Message: {response.message}\")\nprint(f\"Balance: {response.balance}\")\n```\n\n## Usage Examples\n\n### Send Single SMS\n\n```python\nresponse = client.send_sms(\n    phone_number=\"255712345678\", \n    message=\"Hello, this is a test message!\"\n)\n\nif response.success:\n    print(f\"SMS sent successfully! ID: {response.sms_id}\")\n    print(f\"Credits used: {response.credits_spent}\")\n    print(f\"Remaining balance: {response.balance}\")\nelse:\n    print(f\"Failed to send SMS: {response.message}\")\n```\n\n### Send Bulk SMS\n\n```python\nphone_numbers = [\n    \"255712345678\",\n    \"255687654321\", \n    \"255756789012\"\n]\n\nresponse = client.send_bulk_sms(\n    phone_numbers=phone_numbers,\n    message=\"Bulk SMS message to all recipients\"\n)\n\nprint(f\"Total messages: {response.total_messages}\")\nprint(f\"Successful: {response.successful_messages}\")\nprint(f\"Failed: {response.failed_messages}\")\n```\n\n### Send Scheduled SMS\n\n```python\nfrom datetime import datetime, timedelta\n\n# Schedule SMS for tomorrow at 10:00 AM\nschedule_time = datetime.now() + timedelta(days=1)\nschedule_time = schedule_time.replace(hour=10, minute=0, second=0)\n\nresponse = client.send_scheduled_sms(\n    phone_numbers=[\"255712345678\"],\n    message=\"This is a scheduled message\",\n    schedule_time=schedule_time\n)\n\nprint(f\"Scheduled SMS: {response.success}\")\n```\n\n### Send SMS from Excel File\n\nCreate an Excel file with columns: `phone`, `names`, `message` (optional)\n\n```python\n# Using message template with name placeholder\nresponse = client.send_sms_from_excel(\n    file_path=\"contacts.xlsx\",\n    message_template=\"Hello {names}, welcome to our service!\",\n    phone_column=\"phone\",\n    names_column=\"names\"\n)\n\n# Or using individual messages from Excel\nresponse = client.send_sms_from_excel(\n    file_path=\"contacts.xlsx\",\n    message_column=\"message\",\n    phone_column=\"phone\"\n)\n\nprint(f\"Sent {response.successful_messages} out of {response.total_messages} SMS\")\n```\n\n### Check SMS History\n\n```python\nhistory = client.get_sms_history(records=50)\nprint(f\"Retrieved {len(history.get('data', []))} SMS records\")\n```\n\n### Get Sender IDs\n\n```python\nsender_ids = client.get_sender_ids()\nfor sender in sender_ids:\n    print(f\"Sender ID: {sender.name} - Status: {sender.status}\")\n```\n\n## SMS Status and History Tracking\n\nThe Notify Africa Python SDK provides comprehensive methods to track SMS delivery status and retrieve SMS history.\n\n### Check SMS History\n\nRetrieve your SMS sending history with detailed information about each message:\n\n```python\n# Get recent SMS history (default: 50 records)\nhistory = client.get_sms_history()\n\n# Get specific number of records\nhistory = client.get_sms_history(records=100)\n\n# Process the history data\nmessages = history.get('data', [])\nprint(f\"Total messages retrieved: {len(messages)}\")\n\nfor message in messages:\n    print(f\"SMS ID: {message.get('id')}\")\n    print(f\"Recipient: {message.get('recipient')}\")\n    print(f\"Message: {message.get('sms')}\")\n    print(f\"Status: {message.get('status_id')}\")\n    print(f\"Status Description: {message.get('status_description')}\")\n    print(f\"Credits Used: {message.get('credits')}\")\n    print(f\"Sent At: {message.get('created_at')}\")\n    print(f\"Sender ID: {message.get('sender_id')}\")\n    print(\"-\" * 40)\n```\n\n### Check Individual SMS Status\n\nCheck the delivery status of a specific SMS using its ID:\n\n```python\n# Get SMS ID from send response\nresponse = client.send_sms(\"255712345678\", \"Test message\")\nsms_id = response.sms_id\n\n# Check delivery status\nstatus = client.get_delivery_status(sms_id)\n\nif status:\n    print(f\"SMS ID: {status.sms_id}\")\n    print(f\"Recipient: {status.recipient}\")\n    print(f\"Status: {status.status}\")\n    print(f\"Description: {status.status_description}\")\n    print(f\"Credits: {status.credits}\")\nelse:\n    print(\"SMS not found or status unavailable\")\n```\n\n### SMS Status Codes\n\nThe following status codes are commonly returned:\n\n| Status Code | Description |\n|-------------|-------------|\n| `pending` | SMS is queued for delivery |\n| `sent` | SMS has been sent to the carrier |\n| `delivered` | SMS was successfully delivered |\n| `failed` | SMS delivery failed |\n| `expired` | SMS expired before delivery |\n| `rejected` | SMS was rejected by the carrier |\n\n### Advanced History Filtering\n\n```python\n# Get comprehensive SMS history with filtering\ndef get_filtered_sms_history(client, days_back=7, status_filter=None):\n    \"\"\"\n    Get filtered SMS history\n    \n    Args:\n        client: NotifyAfricaClient instance\n        days_back: Number of days to look back\n        status_filter: Filter by specific status (optional)\n    \"\"\"\n    from datetime import datetime, timedelta\n    \n    # Get recent history (API typically returns newest first)\n    history = client.get_sms_history(records=500)\n    messages = history.get('data', [])\n    \n    # Filter by date range\n    cutoff_date = datetime.now() - timedelta(days=days_back)\n    filtered_messages = []\n    \n    for msg in messages:\n        try:\n            # Parse message date\n            msg_date = datetime.fromisoformat(\n                msg.get('created_at', '').replace('Z', '+00:00')\n            )\n            \n            # Check if within date range\n            if msg_date >= cutoff_date:\n                # Apply status filter if specified\n                if status_filter is None or msg.get('status_id') == status_filter:\n                    filtered_messages.append(msg)\n        except:\n            continue\n    \n    return filtered_messages\n\n# Usage examples\nrecent_messages = get_filtered_sms_history(client, days_back=7)\nfailed_messages = get_filtered_sms_history(client, days_back=30, status_filter='failed')\ndelivered_messages = get_filtered_sms_history(client, days_back=7, status_filter='delivered')\n\nprint(f\"Recent messages (7 days): {len(recent_messages)}\")\nprint(f\"Failed messages (30 days): {len(failed_messages)}\")\nprint(f\"Delivered messages (7 days): {len(delivered_messages)}\")\n```\n\n### Bulk Status Checking\n\nCheck status for multiple SMS messages:\n\n```python\ndef check_bulk_sms_status(client, sms_ids):\n    \"\"\"\n    Check status for multiple SMS messages\n    \n    Args:\n        client: NotifyAfricaClient instance\n        sms_ids: List of SMS IDs to check\n    \"\"\"\n    results = []\n    \n    for sms_id in sms_ids:\n        status = client.get_delivery_status(sms_id)\n        if status:\n            results.append({\n                'sms_id': status.sms_id,\n                'recipient': status.recipient,\n                'status': status.status,\n                'description': status.status_description\n            })\n        else:\n            results.append({\n                'sms_id': sms_id,\n                'status': 'not_found',\n                'description': 'SMS not found in history'\n            })\n    \n    return results\n\n# Usage\nsms_ids = ['123', '124', '125']  # Your SMS IDs\nstatuses = check_bulk_sms_status(client, sms_ids)\n\nfor status in statuses:\n    print(f\"SMS {status['sms_id']}: {status['status']} - {status['description']}\")\n```\n\n### Real-time Status Monitoring\n\nMonitor SMS delivery in real-time:\n\n```python\nimport time\nfrom datetime import datetime\n\ndef monitor_sms_delivery(client, sms_id, timeout=300):\n    \"\"\"\n    Monitor SMS delivery status until delivered or timeout\n    \n    Args:\n        client: NotifyAfricaClient instance\n        sms_id: SMS ID to monitor\n        timeout: Maximum time to wait in seconds (default: 5 minutes)\n    \"\"\"\n    start_time = time.time()\n    \n    while time.time() - start_time < timeout:\n        status = client.get_delivery_status(sms_id)\n        \n        if status:\n            print(f\"[{datetime.now().strftime('%H:%M:%S')}] SMS {sms_id}: {status.status}\")\n            \n            # Check if final status reached\n            if status.status in ['delivered', 'failed', 'expired', 'rejected']:\n                return status\n        \n        time.sleep(10)  # Wait 10 seconds before checking again\n    \n    print(f\"Timeout reached for SMS {sms_id}\")\n    return None\n\n# Usage\nresponse = client.send_sms(\"255712345678\", \"Test message\")\nif response.success:\n    final_status = monitor_sms_delivery(client, response.sms_id)\n    if final_status:\n        print(f\"Final status: {final_status.status}\")\n```\n\n### Export SMS History\n\nExport SMS history to different formats:\n\n```python\nimport pandas as pd\nfrom datetime import datetime\n\ndef export_sms_history(client, records=1000, format='csv'):\n    \"\"\"\n    Export SMS history to file\n    \n    Args:\n        client: NotifyAfricaClient instance\n        records: Number of records to export\n        format: Export format ('csv', 'excel', 'json')\n    \"\"\"\n    # Get SMS history\n    history = client.get_sms_history(records=records)\n    messages = history.get('data', [])\n    \n    if not messages:\n        print(\"No SMS history found\")\n        return\n    \n    # Create DataFrame\n    df = pd.DataFrame(messages)\n    \n    # Generate filename with timestamp\n    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')\n    \n    if format.lower() == 'csv':\n        filename = f\"sms_history_{timestamp}.csv\"\n        df.to_csv(filename, index=False)\n    elif format.lower() == 'excel':\n        filename = f\"sms_history_{timestamp}.xlsx\"\n        df.to_excel(filename, index=False)\n    elif format.lower() == 'json':\n        filename = f\"sms_history_{timestamp}.json\"\n        df.to_json(filename, orient='records', indent=2)\n    \n    print(f\"SMS history exported to: {filename}\")\n    return filename\n\n# Usage\nexport_sms_history(client, records=500, format='excel')\n```\n\n### Error Handling for Status Checks\n\n```python\nfrom notify_africa.exceptions import (\n    AuthenticationError,\n    NetworkError,\n    NotifyAfricaException\n)\n\ndef safe_status_check(client, sms_id):\n    \"\"\"Safely check SMS status with error handling\"\"\"\n    try:\n        status = client.get_delivery_status(sms_id)\n        return status\n    except AuthenticationError:\n        print(\"Authentication failed - check your API key\")\n        return None\n    except NetworkError as e:\n        print(f\"Network error: {e}\")\n        return None\n    except NotifyAfricaException as e:\n        print(f\"API error: {e}\")\n        return None\n    except Exception as e:\n        print(f\"Unexpected error: {e}\")\n        return None\n\ndef safe_history_check(client, records=50):\n    \"\"\"Safely get SMS history with error handling\"\"\"\n    try:\n        history = client.get_sms_history(records=records)\n        return history.get('data', [])\n    except AuthenticationError:\n        print(\"Authentication failed - check your API key\")\n        return []\n    except NetworkError as e:\n        print(f\"Network error: {e}\")\n        return []\n    except NotifyAfricaException as e:\n        print(f\"API error: {e}\")\n        return []\n    except Exception as e:\n        print(f\"Unexpected error: {e}\")\n        return []\n\n# Usage\nstatus = safe_status_check(client, \"123\")\nmessages = safe_history_check(client, 100)\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python SDK for Notify Africa SMS Service",
    "version": "1.0.0",
    "project_urls": {
        "Bug Reports": "https://github.com/notify-africa/python-sdk/issues",
        "Documentation": "https://docs.notifyafrica.com",
        "Homepage": "https://github.com/notify-africa/python-sdk",
        "Source": "https://github.com/notify-africa/python-sdk"
    },
    "split_keywords": [
        "sms",
        " tanzania",
        " api",
        " sdk",
        " notify-africa"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0e6d2e47df88f89369367b630d42669d2d7c33bcfbe6cf06fc95e508f1b87366",
                "md5": "7cd4c4b4e32a038cc8839c808d7cd48d",
                "sha256": "daffae32e234b9d9002ca98eed21d5fe8235d5c6893b5907b979e51edc00fec8"
            },
            "downloads": -1,
            "filename": "notify_africa_sms-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7cd4c4b4e32a038cc8839c808d7cd48d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 15736,
            "upload_time": "2025-07-15T14:53:22",
            "upload_time_iso_8601": "2025-07-15T14:53:22.107872Z",
            "url": "https://files.pythonhosted.org/packages/0e/6d/2e47df88f89369367b630d42669d2d7c33bcfbe6cf06fc95e508f1b87366/notify_africa_sms-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8ac8f7947118c1f83e4cfc604ea52d4dc85bd555d836f9d12e6a9316f7739630",
                "md5": "0618e2124b12f30ba25d6d6f7b1dbbf4",
                "sha256": "51b77cb171939e3921ae6f31068141c72eaaa5554aea40c9e0b5eb47788c039c"
            },
            "downloads": -1,
            "filename": "notify_africa_sms-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0618e2124b12f30ba25d6d6f7b1dbbf4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 18095,
            "upload_time": "2025-07-15T14:53:25",
            "upload_time_iso_8601": "2025-07-15T14:53:25.288555Z",
            "url": "https://files.pythonhosted.org/packages/8a/c8/f7947118c1f83e4cfc604ea52d4dc85bd555d836f9d12e6a9316f7739630/notify_africa_sms-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-15 14:53:25",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "notify-africa",
    "github_project": "python-sdk",
    "github_not_found": true,
    "lcname": "notify-africa-sms"
}
        
Elapsed time: 0.56143s