Skip to main content

A client library for sending and managing SMS messages via the SMS Gateway for Android API

Project description

๐Ÿ“ฑ SMS Gateway for Androidโ„ข Python API Client

License PyPI Version Python Version Downloads GitHub Issues GitHub Stars GitHub Forks CodeRabbit Pull Request Reviews

A modern Python client for seamless integration with the SMSGate API. Send SMS messages programmatically through your Android devices with this powerful yet simple-to-use library.

๐Ÿ“– About The Project

The Python client for SMSGate provides a clean, type-safe interface to interact with the SMSGate API. It's designed specifically for Python developers who need to integrate SMS functionality into their applications with minimal setup and maximum reliability.

Key value propositions:

  • ๐Ÿ Pythonic API - Designed with Python conventions and best practices in mind
  • ๐Ÿ›ก๏ธ Robust Security - Guidance for secure credential handling and optional endโ€‘toโ€‘end encryption
  • ๐Ÿ”„ Flexible Architecture - Supports both synchronous and asynchronous programming patterns
  • ๐Ÿ’ป Type Safety - Full type hinting for better developer experience and fewer runtime errors
  • ๐Ÿ”— Webhook Integration - Simplified webhook management for event-driven architectures

This client abstracts away the complexities of the underlying HTTP API while providing all the necessary functionality to send and track SMS messages through Android devices.

๐Ÿ“š Table of Contents

โœจ Features

  • ๐Ÿ”„ Dual Client: Supports both synchronous (APIClient) and asynchronous (AsyncAPIClient) interfaces
  • ๐Ÿ” Flexible Authentication: Supports both Basic Auth and JWT token authentication
  • ๐Ÿ”’ End-to-End Encryption: Optional message encryption using AES-256-CBC
  • ๐ŸŒ Multiple HTTP Backends: Native support for requests, aiohttp, and httpx
  • ๐Ÿ”— Webhook Management: Programmatically create, query, and delete webhooks
  • โš™๏ธ Customizable Base URL: Point to different API endpoints
  • ๐Ÿ’ป Full Type Hinting: Fully typed for better development experience
  • โš ๏ธ Robust Error Handling: Specific exceptions and clear error messages
  • ๐Ÿ“ˆ Delivery Reports: Track your message delivery status
  • ๐Ÿ”‘ Token Management: Generate and revoke JWT tokens with custom scopes and TTL

โš™๏ธ Requirements

  • Python: 3.9 or higher
  • HTTP Client (choose one):
    • ๐Ÿš€ requests (synchronous)
    • โšก aiohttp (asynchronous)
    • ๐ŸŒˆ httpx (synchronous + asynchronous)

Optional Dependencies:

  • ๐Ÿ”’ pycryptodome - For end-to-end encryption support

๐Ÿ“ฆ Installation

Basic Installation

pip install android-sms-gateway

Installation with Specific HTTP Client

# Choose an HTTP client:
pip install android-sms-gateway[requests]    # For synchronous use
pip install android-sms-gateway[aiohttp]     # For asynchronous use
pip install android-sms-gateway[httpx]       # For both synchronous and asynchronous use

Installation with Encryption

# For encrypted messages:
pip install android-sms-gateway[encryption]

# Or install everything:
pip install android-sms-gateway[requests,encryption]

๐Ÿš€ Quickstart

Initial Setup

  1. Configure your credentials:

    export SMSGATE_USERNAME="your_username"
    export SMSGATE_PASSWORD="your_password"
    
  2. Basic usage example:

import asyncio
import os

from android_sms_gateway import client, domain

# Configuration
login = os.getenv("SMSGATE_USERNAME")
password = os.getenv("SMSGATE_PASSWORD")

# Create message
message = domain.Message(
    phone_numbers=["+1234567890"],
    text_message=domain.TextMessage(
        text="Hello! This is a test message.",
    ),
    with_delivery_report=True,
)

# Synchronous Client
def sync_example():
    with client.APIClient(login, password) as c:
        # Send message
        state = c.send(message)
        print(f"Message sent with ID: {state.id}")
        
        # Check status
        status = c.get_state(state.id)
        print(f"Status: {status.state}")

# Asynchronous Client
async def async_example():
    async with client.AsyncAPIClient(login, password) as c:
        # Send message
        state = await c.send(message)
        print(f"Message sent with ID: {state.id}")
        
        # Check status
        status = await c.get_state(state.id)
        print(f"Status: {status.state}")

if __name__ == "__main__":
    print("=== Synchronous Example ===")
    sync_example()
    
    print("\n=== Asynchronous Example ===")
    asyncio.run(async_example())

Encryption Example

from android_sms_gateway import client, domain, Encryptor

# Encryption setup
encryptor = Encryptor("my-super-secure-secret-passphrase")

# Encrypted message
message = domain.Message(
    phone_numbers=["+1234567890"],
    text_message=domain.TextMessage(
        text="This message will be encrypted!"
    ),
)

# Client with encryption
with client.APIClient(login, password, encryptor=encryptor) as c:
    state = c.send(message)
    print(f"Encrypted message sent: {state.id}")

JWT Authentication Example

import os
from android_sms_gateway import client, domain

# Option 1: Using an existing JWT token
jwt_token = os.getenv("ANDROID_SMS_GATEWAY_JWT_TOKEN")

# Create client with JWT token
with client.APIClient(login=None, password=jwt_token) as c:
    message = domain.Message(
        phone_numbers=["+1234567890"],
        text_message=domain.TextMessage(
            text="Hello from JWT authenticated client!",
        ),
    )

# Option 2: Generate a new JWT token with Basic Auth
login = os.getenv("SMSGATE_USERNAME")
password = os.getenv("SMSGATE_PASSWORD")

with client.APIClient(login, password) as c:
    # Generate a new JWT token with specific scopes and TTL
    token_request = domain.TokenRequest(
        scopes=["sms:send", "sms:read"],
        ttl=3600  # Token expires in 1 hour
    )
    token_response = c.generate_token(token_request)
    print(f"New JWT token: {token_response.access_token}")
    print(f"Token expires at: {token_response.expires_at}")
    
    # Use the new token for subsequent requests
    with client.APIClient(login=None, password=token_response.access_token) as jwt_client:
        message = domain.Message(
            phone_numbers=["+1234567890"],
            text_message=domain.TextMessage(
                text="Hello from newly generated JWT token!",
            ),
        )
        state = jwt_client.send(message)
        print(f"Message sent with new JWT token: {state.id}")
        
        # Revoke the token when no longer needed
        jwt_client.revoke_token(token_response.id)
        print(f"Token {token_response.id} has been revoked")

๐Ÿค– Client Guide

Client Configuration

Both clients (APIClient and AsyncAPIClient) support these parameters:

Parameter Type Description Default
login str API username Required (for Basic Auth)
password str API password or JWT token Required
base_url str API base URL "https://api.sms-gate.app/3rdparty/v1"
encryptor Encryptor Encryption instance None
http HttpClient/AsyncHttpClient Custom HTTP client Auto-detected

Authentication Options:

  1. Basic Authentication (traditional):

    client.APIClient(login="username", password="password")
    
  2. JWT Token Authentication:

    # Using an existing JWT token
    client.APIClient(login=None, password="your_jwt_token")
    
    # Or generate a token using Basic Auth first
    with client.APIClient(login="username", password="password") as c:
        token_request = domain.TokenRequest(scopes=["sms:send"], ttl=3600)
        token_response = c.generate_token(token_request)
        
        # Use the new token
        with client.APIClient(login=None, password=token_response.access_token) as jwt_client:
            # Make API calls with JWT authentication
            pass
    

Available Methods

Method Description Return Type
send(message: domain.Message) Send SMS message domain.MessageState
get_state(id: str) Check message status domain.MessageState
create_webhook(webhook: domain.Webhook) Create new webhook domain.Webhook
get_webhooks() List all webhooks List[domain.Webhook]
delete_webhook(id: str) Delete webhook None
generate_token(token_request: domain.TokenRequest) Generate JWT token domain.TokenResponse
revoke_token(jti: str) Revoke JWT token None

Data Structures

Message

class Message:
    message: str                       # Message text
    phone_numbers: List[str]           # List of phone numbers
    with_delivery_report: bool = True  # Delivery report
    is_encrypted: bool = False         # Whether message is encrypted
    
    # Optional fields
    id: Optional[str] = None         # Message ID
    ttl: Optional[int] = None        # Time-to-live in seconds
    sim_number: Optional[int] = None # SIM number

MessageState

class MessageState:
    id: str                          # Unique message ID
    state: ProcessState              # Current state (SENT, DELIVERED, etc.)
    recipients: List[RecipientState] # Per-recipient status
    is_hashed: bool                  # Whether message was hashed
    is_encrypted: bool               # Whether message was encrypted

Webhook

class Webhook:
    id: Optional[str]               # Webhook ID
    url: str                        # Callback URL
    event: WebhookEvent             # Event type

TokenRequest

class TokenRequest:
    scopes: List[str]               # List of scopes for the token
    ttl: Optional[int] = None       # Time to live for the token in seconds

TokenResponse

class TokenResponse:
    access_token: str               # The JWT access token
    token_type: str                 # The type of the token (e.g., 'Bearer')
    id: str                         # The unique identifier of the token (jti)
    expires_at: str                 # The expiration time of the token in ISO format

For more details, see domain.py.

๐ŸŒ HTTP Clients

The library automatically detects installed HTTP clients with this priority:

Client Sync Async
aiohttp โŒ 1๏ธโƒฃ
requests 1๏ธโƒฃ โŒ
httpx 2๏ธโƒฃ 2๏ธโƒฃ

Using Specific Clients

from android_sms_gateway import client, http

# Force httpx usage
client.APIClient(..., http=http.HttpxHttpClient())

# Force requests usage
client.APIClient(..., http=http.RequestsHttpClient())

# Force aiohttp (async only)
async with client.AsyncAPIClient(..., http_client=http.AiohttpHttpClient()) as c:
    # ...

Custom HTTP Client

Implement your own HTTP client following the http.HttpClient (sync) or ahttp.AsyncHttpClient (async) protocols.

๐Ÿ”’ Security

Best Practices

โš ๏ธ IMPORTANT: Always follow these security practices:

  • ๐Ÿ” Credentials: Store credentials in environment variables
  • ๐Ÿšซ Code: Never expose credentials in client-side code
  • ๐Ÿ”’ HTTPS: Use HTTPS for all production communications
  • ๐Ÿ”‘ Encryption: Use end-to-end encryption for sensitive messages
  • ๐Ÿ”„ Rotation: Regularly rotate your credentials

JWT Security Best Practices

When using JWT authentication, follow these additional security practices:

  • โฑ๏ธ Short TTL: Use short time-to-live (TTL) for tokens (recommended: 1 hour or less)
  • ๐Ÿ”’ Secure Storage: Store JWT tokens securely, preferably in memory or secure storage
  • ๐ŸŽฏ Minimal Scopes: Request only the minimum necessary scopes for each token
  • ๐Ÿ”„ Token Rotation: Implement token refresh mechanisms before expiration
  • ๐Ÿ›‘ Revocation: Immediately revoke compromised tokens using revoke_token()

Secure Configuration Example

import os
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Secure configuration
login = os.getenv("SMSGATE_USERNAME")
password = os.getenv("SMSGATE_PASSWORD")

if not login or not password:
    raise ValueError("Credentials not configured!")

๐Ÿ“š API Reference

For complete API documentation including all available methods, request/response schemas, and error codes, visit: ๐Ÿ“˜ Official API Documentation

๐Ÿ‘ฅ Contributing

Contributions are very welcome! ๐ŸŽ‰

How to Contribute

  1. ๐Ÿด Fork the repository
  2. ๐ŸŒฟ Create your feature branch (git checkout -b feature/NewFeature)
  3. ๐Ÿ’พ Commit your changes (git commit -m 'feat: add new feature')
  4. ๐Ÿ“ค Push to branch (git push origin feature/NewFeature)
  5. ๐Ÿ”„ Open a Pull Request

Development Environment

# Clone repository
git clone https://github.com/android-sms-gateway/client-py.git
cd client-py

# Create virtual environment
pipenv install --dev --categories encryption,requests
pipenv shell

Pull Request Checklist

  • Code follows style standards (black, isort, flake8)
  • Tests pass locally
  • Documentation updated
  • Test coverage maintained or improved

๐Ÿ“„ License

This project is licensed under the Apache License 2.0 - see LICENSE for details.

๐Ÿค Support


Note: Android is a trademark of Google LLC. This project is not affiliated with or endorsed by Google.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

android_sms_gateway-3.1.1.tar.gz (30.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

android_sms_gateway-3.1.1-py3-none-any.whl (21.5 kB view details)

Uploaded Python 3

File details

Details for the file android_sms_gateway-3.1.1.tar.gz.

File metadata

  • Download URL: android_sms_gateway-3.1.1.tar.gz
  • Upload date:
  • Size: 30.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for android_sms_gateway-3.1.1.tar.gz
Algorithm Hash digest
SHA256 10355b7ce47fdd9121ad5d4306580c58552a442236683876d420815021404f70
MD5 f680ebd79cbb60dc694ddbe342246ae2
BLAKE2b-256 aed4a3bd62d0f383b16bbc5e19da98301ce0af19cce1813145b009d6a78c858b

See more details on using hashes here.

Provenance

The following attestation bundles were made for android_sms_gateway-3.1.1.tar.gz:

Publisher: publish.yml on android-sms-gateway/client-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file android_sms_gateway-3.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for android_sms_gateway-3.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bb6dc5311404654664739eee4c2cd474a3acc26f7d37f6ca8cbe26eec4bd2055
MD5 2d4413cf6dd75965c5899da891581be1
BLAKE2b-256 dc36378be767834cf78b82e06538d3a9697d4f134bfce6db7db27d4429dd60b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for android_sms_gateway-3.1.1-py3-none-any.whl:

Publisher: publish.yml on android-sms-gateway/client-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page