New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

textbelt-utils

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

textbelt-utils

A lightweight Python package for interacting with the Textbelt SMS API

  • 0.3.2
  • PyPI
  • Socket score

Maintainers
1

textbelt-utils

A lightweight Python package for interacting with the Textbelt SMS API. Send SMS messages, check delivery status, and handle webhook responses with a clean, type-hinted interface.

Features

  • 🚀 Simple, intuitive API
  • 📝 Type hints and dataclasses for better IDE support
  • ✅ Webhook verification
  • 🧪 Test mode support
  • 🔐 One-Time Password (OTP) support
  • 🏢 Custom sender name support
  • 📨 Bulk SMS support with rate limiting
  • ⚡ Async/sync clients for flexibility
  • 0️⃣ Zero external dependencies beyond requests

Installation

pip install textbelt-utils

Quick Start

from textbelt_utils import TextbeltClient, SMSRequest

# Initialize client
client = TextbeltClient(api_key="your_api_key")

# Send an SMS
request = SMSRequest(
    phone="+1234567890",
    message="Hello from textbelt-utils!",
    key="your_api_key"
)

response = client.send_sms(request)
print(f"Message sent! ID: {response.text_id}")

Features

Send SMS

from textbelt_utils import TextbeltClient, SMSRequest

client = TextbeltClient(api_key="your_api_key")

# Basic SMS
request = SMSRequest(
    phone="+1234567890",
    message="Hello!",
    key="your_api_key"
)

# SMS with webhook for replies
request_with_webhook = SMSRequest(
    phone="+1234567890",
    message="Reply to this message!",
    key="your_api_key",
    reply_webhook_url="https://your-site.com/webhook",
    webhook_data="custom_data"
)

# SMS with custom sender name
request_with_sender = SMSRequest(
    phone="+1234567890",
    message="Message from your company!",
    key="your_api_key",
    sender="MyCompany"  # Set a custom sender name for this message
)

response = client.send_sms(request)

Bulk SMS

Send multiple SMS messages efficiently with rate limiting and batching:

from textbelt_utils import TextbeltClient, BulkSMSRequest

client = TextbeltClient(api_key="your_api_key")

# Send same message to multiple recipients
request = BulkSMSRequest(
    phones=["+1234567890", "+1987654321"],
    message="Broadcast message to all recipients!",
    batch_size=100,  # Process in batches of 100
    delay_between_messages=0.1  # 100ms delay between messages
)

# Or send individual messages to each recipient
request = BulkSMSRequest(
    phones=["+1234567890", "+1987654321"],
    individual_messages={
        "+1234567890": "Custom message for recipient 1",
        "+1987654321": "Different message for recipient 2"
    },
    batch_size=100,
    delay_between_messages=0.1
)

response = client.send_bulk_sms(request)
print(f"Total messages: {response.total_messages}")
print(f"Successful: {response.successful_messages}")
print(f"Failed: {response.failed_messages}")

# Check individual results
for phone, result in response.results.items():
    if result.text_id:
        status = client.check_status(result.text_id)
        print(f"{phone}: {status.status}")

Async Bulk SMS

Send messages concurrently with proper rate limiting:

from textbelt_utils import AsyncTextbeltClient, BulkSMSRequest
import asyncio

async def send_bulk():
    async with AsyncTextbeltClient(api_key="your_api_key") as client:
        request = BulkSMSRequest(
            phones=["+1234567890", "+1987654321"],
            message="Async bulk message!",
            batch_size=100,  # Process 100 messages concurrently
            delay_between_messages=0.1
        )
        
        response = await client.send_bulk_sms(request)
        print(f"Sent: {response.successful_messages}")
        print(f"Failed: {response.failed_messages}")

asyncio.run(send_bulk())

Sender Name

You can set a sender name for your SMS messages in two ways:

  1. Account-wide: Set a default sender name in your Textbelt account settings at https://textbelt.com/account
  2. Per-message: Set the sender parameter in your SMSRequest

The sender name is used for compliance purposes and helps recipients identify who sent the message. If you don't specify a sender name, Textbelt will automatically append your default sender name to the message (unless it already appears in the message content).

# Example with custom sender name
request = SMSRequest(
    phone="+1234567890",
    message="Important update!",
    key="your_api_key",
    sender="MyCompany"  # This overrides your account's default sender name
)

Note: The sender name is used strictly for compliance purposes and does not override the "From" number for the SMS sender.

Check Message Status

status = client.check_status("text_id")
print(f"Message status: {status.status}")  # DELIVERED, SENT, SENDING, etc.

Check Quota

quota = client.check_quota()
print(f"Remaining messages: {quota.quota_remaining}")

Test Mode

# Send a test message (doesn't use quota)
response = client.send_test(request)

Webhook Verification

from textbelt_utils.utils import verify_webhook

is_valid = verify_webhook(
    api_key="your_api_key",
    timestamp="webhook_timestamp",
    signature="webhook_signature",
    payload="webhook_payload"
)

One-Time Password (OTP)

The package provides built-in support for generating and verifying one-time passwords:

from textbelt_utils import AsyncTextbeltClient, OTPGenerateRequest, OTPVerifyRequest

async def handle_otp():
    async with AsyncTextbeltClient(api_key="your_api_key") as client:
        # Generate and send OTP
        generate_request = OTPGenerateRequest(
            phone="+1234567890",
            userid="user@example.com",  # Unique identifier for your user
            key="your_api_key",
            message="Your verification code is $OTP",  # Optional custom message
            lifetime=180,  # Optional validity duration in seconds (default: 180)
            length=6      # Optional code length (default: 6)
        )
        
        response = await client.generate_otp(generate_request)
        print(f"OTP sent! Message ID: {response.text_id}")
        
        # Later, verify the OTP entered by the user
        verify_request = OTPVerifyRequest(
            otp="123456",    # Code entered by user
            userid="user@example.com",  # Same userid used in generate
            key="your_api_key"
        )
        
        verify_response = await client.verify_otp(verify_request)
        if verify_response.is_valid_otp:
            print("OTP verified successfully!")
        else:
            print("Invalid OTP")
OTP Features
  • Custom Messages: Use the $OTP placeholder in your message to control where the code appears
  • Configurable Lifetime: Set how long the code remains valid (30-3600 seconds)
  • Configurable Length: Choose the number of digits in the code (4-10 digits)
  • No Extra Cost: OTP functionality is included in your regular SMS quota
  • Automatic Cleanup: Invalid/expired codes are automatically cleaned up
  • Input Validation: Built-in validation for phone numbers, message length, and code format

Error Handling

The package provides specific exceptions for different error cases:

from textbelt_utils.exceptions import (
    QuotaExceededError,
    InvalidRequestError,
    WebhookVerificationError,
    APIError
)

try:
    response = client.send_sms(request)
except QuotaExceededError:
    print("Out of quota!")
except InvalidRequestError as e:
    print(f"Invalid request: {e}")
except WebhookVerificationError:
    print("Webhook verification failed")
except APIError as e:
    print(f"API error: {e}")

Asynchronous Usage

from textbelt_utils import AsyncTextbeltClient, SMSRequest
import asyncio

async def main():
    async with AsyncTextbeltClient(api_key="your_api_key") as client:
        # Send SMS
        request = SMSRequest(
            phone="+1234567890",
            message="Async hello!",
            key="your_api_key"
        )
        response = await client.send_sms(request)
        
        # Check status
        status = await client.check_status(response.text_id)
        
        # Check quota
        quota = await client.check_quota()

if __name__ == "__main__":
    asyncio.run(main())

Mixed Sync/Async Usage

from textbelt_utils import TextbeltClient, AsyncTextbeltClient, SMSRequest

# Synchronous
sync_client = TextbeltClient(api_key="your_api_key")
sync_response = sync_client.send_sms(request)

# Asynchronous
async def send_async():
    async with AsyncTextbeltClient(api_key="your_api_key") as client:
        async_response = await client.send_sms(request)

Development

Environment Setup

  1. Copy the environment template:
cp .env.template .env
  1. Edit .env with your configuration:
# Textbelt API Configuration
TEXTBELT_API_KEY=your_api_key_here

# Test Phone Numbers (E.164 format)
TEXTBELT_TEST_PHONE=your_test_phone_here
TEXTBELT_TEST_PHONE2=your_second_test_phone_here

The package automatically loads environment variables from your .env file on import. You can also explicitly load or reload configuration:

from textbelt_utils import load_config, get_env_var

# Load default .env file
load_config()

# Load specific env file
load_config(".env.test")

# Get environment variables with helpful error messages
api_key = get_env_var('TEXTBELT_API_KEY')
test_phone = get_env_var('TEXTBELT_TEST_PHONE')

# Get with default value
debug_mode = get_env_var('DEBUG', 'false')

For testing, you can use .env.test which contains safe test values:

# Use test environment
cp .env.test .env

# Or specify a different env file in code
load_config(".env.test")

Running Tests

poetry run python -m unittest discover tests

Testing Your Integration

Testing SMS

The package includes test scripts in the scripts directory to help you verify your Textbelt integration. To use them:

  1. Set up your environment variables:
export TEXTBELT_API_KEY=your_api_key_here
export TEXTBELT_TEST_PHONE=your_phone_number_here  # E.164 format, e.g., +1234567890
  1. Run the test scripts:
# Test basic SMS
poetry run python scripts/test_send.py

# Test async SMS
poetry run python scripts/test_send_async.py

# Test bulk SMS
poetry run python scripts/test_bulk_send.py

The scripts will:

  • Send test messages (using test mode, won't use your quota)
  • Display message IDs and delivery status
  • Show your remaining quota

Testing OTP

The package also includes an OTP test script:

# Using environment variables
poetry run python scripts/test_otp.py

# Or provide values directly
poetry run python scripts/test_otp.py --phone +1234567890 --key your_api_key

Security Note

  • Never commit test scripts with actual phone numbers or API keys
  • Always use environment variables for sensitive data
  • Add test scripts to your .gitignore if you modify them with any sensitive data

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

TODO

High Priority

  • Add comprehensive webhook support
    • Add webhook handler/router functionality
    • Add webhook signature verification middleware
    • Add example webhook handlers for common use cases
    • Document webhook payload structure and events
    • Add webhook testing utilities
  • Add retry mechanism for failed API calls

Medium Priority

  • Add rate limiting configuration options
  • Add logging configuration options
  • Add support for scheduling messages
  • Add support for message templates
  • Add support for contact lists/groups

Low Priority

  • Add message history tracking
  • Add support for delivery reports
  • Add support for analytics and reporting
  • Add CLI tool for common operations

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc