Official Python SDK for sed.sh API - URL shortening, malware scanning, disposable email, mock APIs, and PDF reports
Project description
sed.sh Python SDK
Official Python client library for sed.sh API - providing URL shortening, malware scanning, disposable email, mock APIs, and PDF report generation.
Features
- Links: Create, manage, and track shortened URLs with optional password protection
- Malware Scanner: Scan files for malware using AWS GuardDuty
- Disposable Inbox: Create temporary email addresses for testing
- Mock APIs: Create mock HTTP endpoints for testing and development
- PDF Reports: Generate PDF documents from HTML templates with JSON data
- Both Sync and Async: Full support for synchronous and asynchronous operations
- CLI Tool: Command-line interface for all services
- Type Hints: Full typing support for better IDE autocomplete
- 🆕 Mailosaur Compatibility: Drop-in replacement for Mailosaur SDK - migrate by just changing imports!
Installation
pip install sed-sh
Quick Start
Synchronous Usage
from sed_sh import SedSH
# Initialize client with API key
client = SedSH(api_key="your_api_key_here")
# Create a short link
link = client.links.create("https://example.com/very/long/url")
print(f"Short URL: {link['shortUrl']}")
# Scan a file for malware
scan = client.malware.scan_file("/path/to/file.pdf")
print(f"Scan status: {scan['status']}")
# Create a disposable inbox
inbox = client.inbox.create()
print(f"Email address: {inbox['email']}")
# Create a mock API endpoint
endpoint = client.routes.create_endpoint(
name="Test API",
method="POST",
path="/api/test",
response_status=200,
response_body='{"success": true}'
)
print(f"Mock URL: {endpoint['url']}")
# Generate a PDF from template
template = client.reports.create_template(
name="Invoice",
html="<h1>Invoice for {{customer}}</h1>"
)
pdf = client.reports.generate_pdf(
template['templateId'],
{"customer": "John Doe"}
)
print(f"PDF URL: {pdf['downloadUrl']}")
Asynchronous Usage
import asyncio
from sed_sh import AsyncSedSH
async def main():
# Initialize async client
client = AsyncSedSH(api_key="your_api_key_here")
# Create a short link
link = await client.links.create("https://example.com")
print(f"Short URL: {link['shortUrl']}")
# Scan a file
scan = await client.malware.scan_file("/path/to/file.pdf")
print(f"Scan status: {scan['status']}")
# Close the session when done
await client.close()
asyncio.run(main())
Using Context Managers
# Sync context manager
with SedSH(api_key="your_api_key") as client:
link = client.links.create("https://example.com")
print(link['shortUrl'])
# Async context manager
async with AsyncSedSH(api_key="your_api_key") as client:
link = await client.links.create("https://example.com")
print(link['shortUrl'])
Authentication
The SDK supports multiple authentication methods:
1. Constructor Parameter
client = SedSH(api_key="your_api_key")
2. Environment Variable
export SEDSH_API_KEY="your_api_key"
client = SedSH() # Automatically uses SEDSH_API_KEY
3. Config File
Create ~/.sedsh/config.json:
{
"api_key": "your_api_key",
"base_url": "https://api.sed.sh"
}
client = SedSH() # Automatically loads from config file
CLI Usage
The SDK includes a command-line interface:
# Set API key
export SEDSH_API_KEY="your_api_key"
# Links
sedsh links create https://example.com
sedsh links create https://example.com --password secret123
sedsh links list
sedsh links delete abc12
# Malware
sedsh malware scan /path/to/file.pdf
# Inbox
sedsh inbox create
sedsh inbox list
sedsh inbox messages <inbox-code>
sedsh inbox delete <inbox-code>
# Routes
sedsh routes create "Test API" POST /api/test --status 200 --body '{"ok": true}'
sedsh routes list
sedsh routes delete <endpoint-id>
# Reports
sedsh reports create-template "Invoice" /path/to/template.html
sedsh reports generate <template-id> '{"customer": "John"}'
sedsh reports list-templates
API Reference
Links Service
# Create a link
link = client.links.create(
target_url="https://example.com",
password="optional_password" # Optional
)
# List all links
links = client.links.list()
# Delete a link
client.links.delete(code="abc12")
Malware Service
# Scan a file
scan = client.malware.scan_file(
file_path="/path/to/file.pdf"
)
# Returns: {'scanId': '...', 'status': 'pending', 'fileName': '...'}
# Note: Scan results are sent via email notification
Inbox Service
# Create an inbox
inbox = client.inbox.create()
# List all inboxes
inboxes = client.inbox.list()
# Get messages for an inbox
messages = client.inbox.get_messages(inbox_code="inbox_123")
# Get a specific message
message = client.inbox.get_message(
inbox_code="inbox_123",
message_id="msg_456"
)
# Delete a message
client.inbox.delete_message(
inbox_code="inbox_123",
message_id="msg_456"
)
# Delete an inbox
client.inbox.delete(inbox_code="inbox_123")
Routes Service
# Create a mock endpoint
endpoint = client.routes.create_endpoint(
name="User API",
method="POST",
path="/api/users",
response_status=200,
response_body='{"success": true}',
response_headers={"Content-Type": "application/json"}, # Optional
response_delay=0, # Optional, milliseconds
enabled=True # Optional
)
# Create a forward endpoint (proxy mode)
endpoint = client.routes.create_endpoint(
name="Proxy API",
method="GET",
path="/api/proxy",
forward_mode=True,
forward_url="https://api.example.com/endpoint"
)
# List endpoints
endpoints = client.routes.list_endpoints()
# Update an endpoint
updated = client.routes.update_endpoint(
endpoint_id="endpoint_123",
name="Updated API",
response_status=201
)
# Toggle endpoint enabled/disabled
client.routes.toggle_endpoint(
endpoint_id="endpoint_123",
enabled=False
)
# Get requests received by endpoints
requests = client.routes.get_requests()
# Get details of a specific request
request_details = client.routes.get_request(request_id="req_123")
# Delete an endpoint
client.routes.delete_endpoint(endpoint_id="endpoint_123")
Reports Service
# Create a template
template = client.reports.create_template(
name="Invoice Template",
html="<h1>Invoice #{{invoice_number}}</h1>",
expiry_hours=24 # Optional, max 24
)
# List templates
templates = client.reports.list_templates()
# Get template HTML
html = client.reports.get_template(template_id="tpl_123")
# Generate PDF from template
pdf = client.reports.generate_pdf(
template_id="tpl_123",
data={
"invoice_number": "INV-001",
"customer": "John Doe",
"amount": "$100.00"
}
)
# Returns: {'downloadUrl': '...', 'generationId': '...', 'expiresAt': ...}
# List recent PDF generations
generations = client.reports.list_generations()
# Delete a template
client.reports.delete_template(template_id="tpl_123")
Error Handling
from sed_sh import SedSH
from sed_sh.exceptions import (
SedSHError,
AuthenticationError,
RateLimitError,
ResourceNotFoundError,
InvalidRequestError,
)
client = SedSH(api_key="your_api_key")
try:
link = client.links.create("https://example.com")
except AuthenticationError as e:
print(f"Invalid API key: {e}")
except RateLimitError as e:
print(f"Rate limit exceeded: {e}")
except ResourceNotFoundError as e:
print(f"Resource not found: {e}")
except InvalidRequestError as e:
print(f"Invalid request: {e}")
except SedSHError as e:
print(f"API error: {e}")
Important Notes
⚠️ This SDK does NOT include automatic retries or request timeouts. You should implement these in your application if needed:
# Example: Manual retry logic
from time import sleep
def create_link_with_retry(client, url, max_retries=3):
for attempt in range(max_retries):
try:
return client.links.create(url)
except SedSHError as e:
if attempt == max_retries - 1:
raise
sleep(2 ** attempt) # Exponential backoff
⚠️ This SDK does NOT perform client-side input validation. Invalid inputs will be caught by the API and return appropriate errors.
Configuration Options
client = SedSH(
api_key="your_api_key", # API key (required if not in env/config)
base_url="https://api.sed.sh", # API base URL (optional)
timeout=30, # Request timeout in seconds (optional)
)
Development
# Clone the repository
git clone https://github.com/triellocom/sed-sh-sdk.git
cd sed-sh-sdk/python
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black sed_sh/
# Type checking
mypy sed_sh/
Mailosaur Compatibility Adapter
Migrating from Mailosaur? The sed.sh SDK includes a drop-in replacement adapter that allows you to migrate with minimal code changes.
Quick Migration (30 seconds)
# BEFORE: Using Mailosaur
# from mailosaur import MailosaurClient
# from mailosaur.models import SearchCriteria
# AFTER: Using sed.sh (just change the import!)
from sed_sh.adapters.mailosaur import MailosaurClient, SearchCriteria
# Everything else stays the same!
mailosaur = MailosaurClient(api_key=os.environ['SEDSH_API_KEY'])
# Generate test email
test_email = mailosaur.servers.generate_email_address()
# Wait for email
criteria = SearchCriteria()
criteria.sent_to = test_email
server_id = test_email.split('@')[0]
message = mailosaur.messages.get(server_id, criteria, timeout=30000)
# Extract verification link
if message['html']['links']:
verify_link = message['html']['links'][0]['href']
print(f"Verification link: {verify_link}")
# Extract OTP code
if message['text']['codes']:
otp = message['text']['codes'][0]
print(f"OTP: {otp}")
What Changed
- ✅ Import statement:
from sed_sh.adapters.mailosaur import ... - ✅ API key: Use
SEDSH_API_KEYinstead ofMAILOSAUR_API_KEY - ✅ Email generation: Use
generate_email_address()(no wildcard domain)
What Stayed the Same
- ✅ All API methods:
messages.get(),servers.list(), etc. - ✅
SearchCriteriausage - ✅ Message structure and data access
- ✅ Your test logic
Complete Migration Guide
See MAILOSAUR_MIGRATION.md for:
- Complete before/after examples
- API compatibility matrix
- Pytest integration patterns
- Troubleshooting guide
- Migration example script
Examples
See the examples/ directory for complete examples:
links_sync.py- Synchronous link managementlinks_async.py- Asynchronous link managementmalware_sync.py- File scanninginbox_sync.py- Disposable email managementroutes_sync.py- Mock API endpoint creationreports_sync.py- PDF generationmailosaur_migration_example.py- NEW: Mailosaur compatibility demonstration
Requirements
- Python 3.8 or higher
requests>= 2.25.0aiohttp>= 3.8.0click>= 8.0.0
License
MIT License - see LICENSE file for details.
Support
- Documentation: https://www.sed.sh/docs
- Issues: https://github.com/triellocom/sed-sh-sdk/issues
- Email: support@sed.sh
Links
- Website: https://www.sed.sh
- API Documentation: https://www.sed.sh/docs
- PyPI: https://pypi.org/project/sed-sh/
Testing
The SDK includes a comprehensive test suite using pytest.
Running Tests
# Install development dependencies
pip install -e .[dev]
# Run all tests
make test
# Run with coverage
make test-cov
# Run integration tests (requires API key)
export SEDSH_API_KEY="your-api-key"
make test-integration
Test Structure
tests/test_exceptions.py- Exception handling teststests/test_client.py- Client initialization teststests/test_services_integration.py- API integration tests
See README_TESTING.md for detailed testing documentation.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sed_sh-0.7.0.tar.gz.
File metadata
- Download URL: sed_sh-0.7.0.tar.gz
- Upload date:
- Size: 87.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24cf488d26d8dfeb583b72a8e9379265effd52fe2543c950285ead7d4bb4382b
|
|
| MD5 |
f5087d3d065cc99c5ff2bda902f3c1e5
|
|
| BLAKE2b-256 |
424642f5e02a94bcb74eeecff06727aa125f7a60838dcc75a3393aa3bcb7b94b
|
File details
Details for the file sed_sh-0.7.0-py3-none-any.whl.
File metadata
- Download URL: sed_sh-0.7.0-py3-none-any.whl
- Upload date:
- Size: 70.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a425cd161974a67111547fbe8ab7ac792df2f11f3e57dc5d64b2585887d0957
|
|
| MD5 |
762a6c45c4e7afdb54337b072e0f571d
|
|
| BLAKE2b-256 |
5ac83984d6965536b4a3a327630028ffd017dd1c36ff120df9e2949b145b2aef
|