
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
sendly
Advanced tools
Official Python SDK for Sendly - SMS for developers.
pip install sendly
from sendly import Sendly
# Initialize the client
client = Sendly(api_key='sl_test_your_api_key_here')
# Send an SMS
response = client.sms.send(
to='+14155552671',
text='Hello from Sendly!'
)
print(f"Message sent! ID: {response.id}")
Get your API key from the Sendly Dashboard.
export SENDLY_API_KEY="sl_test_your_api_key_here"
from sendly import Sendly
# API key automatically loaded from environment
client = Sendly()
client = Sendly(api_key='sl_test_your_api_key_here')
client = Sendly(
api_key='sl_test_your_api_key_here',
base_url='https://api.sendly.live',
timeout=30.0,
max_retries=3
)
response = client.sms.send(
to='+14155552671',
text='Hello from Sendly!'
)
print(f"Message ID: {response.id}")
print(f"Status: {response.status}")
print(f"From: {response.from_}")
print(f"Cost: ${response.cost.amount}")
# Transactional messages
client.sms.send(
to='+14155552671',
text='Your order #12345 has shipped!',
message_type='transactional'
)
# OTP/Verification messages
client.sms.send(
to='+14155552671',
text='Your verification code: 123456',
message_type='otp'
)
# Marketing messages
client.sms.send(
to='+14155552671',
text='50% off sale this weekend!',
message_type='marketing'
)
with Sendly(api_key='sl_test_your_api_key_here') as client:
response = client.sms.send(
to='+14155552671',
text='Hello from Sendly!'
)
response = client.sms.send(
to='+14155552671',
text='Your verification code: 789012',
webhook_url='https://myapp.com/webhook/sms',
webhook_failover_url='https://myapp.com/webhook/backup'
)
response = client.sms.send(
to='+14155552671',
text='Welcome to our platform!',
tags=['onboarding', 'welcome', 'user-123']
)
import time
recipients = [
{'phone': '+14155552671', 'name': 'Alice'},
{'phone': '+14155552672', 'name': 'Bob'},
{'phone': '+14155552673', 'name': 'Charlie'}
]
for recipient in recipients:
try:
response = client.sms.send(
to=recipient['phone'],
text=f"Hello {recipient['name']}!",
tags=['batch', f"user-{recipient['name'].lower()}"]
)
print(f"Sent to {recipient['name']}: {response.id}")
except Exception as e:
print(f"Failed to send to {recipient['name']}: {e}")
time.sleep(0.1)
from sendly.errors import (
ValidationError,
AuthenticationError,
RateLimitError,
APIError
)
try:
response = client.sms.send(
to='+14155552671',
text='Hello Sendly!'
)
except ValidationError as e:
print(f"Validation error: {e.message}")
except AuthenticationError as e:
print(f"Authentication error: {e.message}")
except RateLimitError as e:
print(f"Rate limit error: {e.message}")
if e.retry_after:
print(f"Retry after: {e.retry_after} seconds")
except APIError as e:
print(f"API error: {e.message}")
print(f"Status code: {e.status_code}")
Use test API keys for development. The sandbox provides magic numbers for testing different scenarios:
| Phone Number | Behavior |
|---|---|
+15550001234 | Instant delivery |
+15550001010 | 10 second delay |
+15550001030 | 30 second delay |
| Phone Number | Error Type | HTTP Status |
|---|---|---|
+15550009999 | Invalid number | 400 |
+15550009998 | Carrier rejection | 400 |
+15550009997 | Rate limit exceeded | 429 |
+15550009996 | Timeout error | 500 |
Example:
from sendly import Sendly
from sendly.errors import RateLimitError
# Initialize with test API key
client = Sendly(api_key='sl_test_YOUR_TEST_KEY')
# Test instant success
response = client.sms.send(
to='+15550001234',
text='Testing instant delivery'
)
print(f"Success: {response.status}")
# Test rate limit error
try:
response = client.sms.send(
to='+15550009997',
text='Testing rate limit'
)
except RateLimitError as e:
print(f"Rate limit error: {e.message}")
print(f"Retry after: {e.retry_after} seconds")
Sendly(
api_key: str = None,
base_url: str = "https://api.sendly.live",
timeout: float = 30.0,
max_retries: int = 3
)
client.sms.send()client.sms.send(
to: str,
text: str,
from_: str = None,
message_type: str = None,
webhook_url: str = None,
webhook_failover_url: str = None,
tags: List[str] = None
) -> SMSResponse
Parameters:
to - Destination phone number (E.164 format)text - Message text (required)from_ - Sender number (auto-selected if not provided)message_type - Message type: transactional, otp, marketing, alertwebhook_url - HTTPS webhook URL for delivery notificationswebhook_failover_url - HTTPS backup webhook URLtags - Message tags for analytics (max 20, 50 chars each)SMSResponseclass SMSResponse:
id: str
status: str
from_: str
to: str
text: str
created_at: str
segments: int
cost: CostInfo
routing: RoutingInfo
# Install development dependencies
pip install -e ".[dev]"
# Run unit tests
pytest tests/unit/
# Run integration tests
pytest tests/integration/
# Run all tests with coverage
pytest --cov=sendly --cov-report=html
# Clone the repository
git clone https://github.com/sendly-live/sendly-python.git
cd sendly-python
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Run linting
flake8 sendly/
black sendly/
isort sendly/
MIT
FAQs
The official Python SDK for Sendly - the Resend of SMS
We found that sendly demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.