π± SMS Gateway for Androidβ’ Python API Client

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):
Optional Dependencies:
π¦ Installation
Basic Installation
pip install android-sms-gateway
Installation with Specific HTTP Client
pip install android-sms-gateway[requests]
pip install android-sms-gateway[aiohttp]
pip install android-sms-gateway[httpx]
Installation with Encryption
pip install android-sms-gateway[encryption]
pip install android-sms-gateway[requests,encryption]
π Quickstart
Initial Setup
import asyncio
import os
from android_sms_gateway import client, domain
login = os.getenv("ANDROID_SMS_GATEWAY_LOGIN")
password = os.getenv("ANDROID_SMS_GATEWAY_PASSWORD")
message = domain.Message(
"Hello! This is a test message.",
["+1234567890"],
with_delivery_report=True
)
def sync_example():
with client.APIClient(login, password) as c:
state = c.send(message)
print(f"Message sent with ID: {state.id}")
status = c.get_state(state.id)
print(f"Status: {status.state}")
async def async_example():
async with client.AsyncAPIClient(login, password) as c:
state = await c.send(message)
print(f"Message sent with ID: {state.id}")
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
encryptor = Encryptor("my-super-secure-secret-passphrase")
message = domain.Message(
"This message will be encrypted!",
["+1234567890"],
is_encrypted=True
)
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
jwt_token = os.getenv("ANDROID_SMS_GATEWAY_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!",
),
)
login = os.getenv("ANDROID_SMS_GATEWAY_LOGIN")
password = os.getenv("ANDROID_SMS_GATEWAY_PASSWORD")
with client.APIClient(login, password) as c:
token_request = domain.TokenRequest(
scopes=["sms:send", "sms:read"],
ttl=3600
)
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}")
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}")
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:
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:
-
Basic Authentication (traditional):
client.APIClient(login="username", password="password")
-
JWT Token Authentication:
client.APIClient(login=None, password="your_jwt_token")
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)
with client.APIClient(login=None, password=token_response.access_token) as jwt_client:
pass
Available Methods
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
phone_numbers: List[str]
with_delivery_report: bool = True
is_encrypted: bool = False
id: Optional[str] = None
ttl: Optional[int] = None
sim_number: Optional[int] = None
MessageState
class MessageState:
id: str
state: ProcessState
recipients: List[RecipientState]
is_hashed: bool
is_encrypted: bool
Webhook
class Webhook:
id: Optional[str]
url: str
event: WebhookEvent
TokenRequest
class TokenRequest:
scopes: List[str]
ttl: Optional[int] = None
TokenResponse
class TokenResponse:
access_token: str
token_type: str
id: str
expires_at: str
For more details, see domain.py.
π HTTP Clients
The library automatically detects installed HTTP clients with this priority:
| aiohttp | β | 1οΈβ£ |
| requests | 1οΈβ£ | β |
| httpx | 2οΈβ£ | 2οΈβ£ |
Using Specific Clients
from android_sms_gateway import client, http
client.APIClient(..., http=http.HttpxHttpClient())
client.APIClient(..., http=http.RequestsHttpClient())
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_dotenv()
login = os.getenv("ANDROID_SMS_GATEWAY_LOGIN")
password = os.getenv("ANDROID_SMS_GATEWAY_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
- π΄ Fork the repository
- πΏ Create your feature branch (
git checkout -b feature/NewFeature)
- πΎ Commit your changes (
git commit -m 'feat: add new feature')
- π€ Push to branch (
git push origin feature/NewFeature)
- π Open a Pull Request
Development Environment
git clone https://github.com/android-sms-gateway/client-py.git
cd client-py
pipenv install --dev --categories encryption,requests
pipenv shell
Pull Request Checklist
π 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.