Loops SDK for Python
Project description
Loops SDK for Python
A self-contained Python module that acts as a Loops.so SDK, providing the same interfaces as the existing Loops SDKs for sending transactional emails.
Features
- Complete API Coverage: Supports all transactional email types (invite, validation, password reset)
- Type Safety: Uses Python dataclasses and type hints for better development experience
- Error Handling: Comprehensive error handling with meaningful error messages
- Testing: Extensive test suite with mocking for external API calls
- Easy Integration: Simple, intuitive API that mirrors other Loops SDK
Installation
Add loops-sdk to your project. pip install loops-sdk
Dependencies
The SDK requires the following Python packages:
requests(for HTTP API calls)
Quick Start
from loops_sdk import LoopsClient, send_transactional_email
# Initialize the client
client = LoopsClient(api_key="your-loops-api-key")
# Or use environment variable LOOPS_TOKEN
client = LoopsClient()
# Send an invite email
response = send_transactional_email(
client=client,
email="newuser@example.com",
transactional_id="your-custom-template-id",
add_to_audience=True,
data_variables={
"customerName": "Alice Johnson",
"invoiceNumber": "INV-001",
"amount": "$99.99"
},
attachments=[attachment]
)
print(f"Email sent successfully: {response}")
API Reference
LoopsClient
The main client class for interacting with the Loops API.
client = LoopsClient(api_key="your-api-key")
Parameters:
api_key(optional): Your Loops API key. If not provided, will use theLOOPS_TOKENenvironment variable.
Email Constructor Functions
mk_invite_email(email, inviter_name, invite_url)
Creates an invite email object.
Parameters:
email: Recipient's email addressinviter_name: Name of the person sending the inviteinvite_url: URL for the invitation
Returns: LoopsEmail object
mk_validation_email(email, name, verification_url)
Creates a validation email object.
Parameters:
email: Recipient's email addressname: Recipient's nameverification_url: URL for email verification
Returns: LoopsEmail object
mk_password_reset_email(email, name, reset_url)
Creates a password reset email object.
Parameters:
email: Recipient's email addressname: Recipient's namereset_url: URL for password reset
Returns: LoopsEmail object
Usage Examples
Basic Usage
from loops_sdk import LoopsClient, mk_invite_email
# Initialize client
client = LoopsClient(api_key="your-api-key")
# Create and send an invite email
invite_email = mk_invite_email(
email="user@example.com",
inviter_name="John Doe",
invite_url="https://example.com/invite/123"
)
response = client.send_transactional_email(invite_email)
Using Environment Variables
import os
from loops_sdk import LoopsClient, send_validation_email
# Set environment variable
os.environ["LOOPS_TOKEN"] = "your-api-key"
# Client will automatically use the environment variable
client = LoopsClient()
# Send validation email
response = send_validation_email(
client=client,
email="user@example.com",
name="Jane Smith",
verification_url="https://example.com/verify/abc123"
)
Error Handling
import requests
from loops_sdk import LoopsClient, send_password_reset_email
client = LoopsClient(api_key="your-api-key")
try:
response = send_password_reset_email(
client=client,
email="user@example.com",
name="Bob Johnson",
reset_url="https://example.com/reset/xyz789"
)
print("Email sent successfully!")
except requests.HTTPError as e:
print(f"Failed to send email: {e}")
except ValueError as e:
print(f"Configuration error: {e}")
Custom Email with Attachments
from loops_sdk import LoopsClient, LoopsEmail, Attachment
client = LoopsClient(api_key="your-api-key")
# Create an attachment
attachment = Attachment(
filename="invoice.pdf",
content_type="application/pdf",
data="base64-encoded-data-here"
)
# Create custom email
custom_email = LoopsEmail(
email="customer@example.com",
transactional_id="your-custom-template-id",
add_to_audience=True,
data_variables={
"customerName": "Alice Johnson",
"invoiceNumber": "INV-001",
"amount": "$99.99"
},
attachments=[attachment]
)
response = client.send_transactional_email(custom_email)
Testing
The SDK includes a comprehensive test suite. To run the tests:
python test_loops_sdk.py
Test Coverage
The test suite covers:
- Email object creation and serialization
- API client initialization and configuration
- Successful API calls with mocked responses
- Error handling for failed API calls
- All convenience functions
- Integration workflows
- Edge cases and error conditions
Running Tests with Coverage
pip install coverage
coverage run test_loops_sdk.py
coverage report -m
Compatibility
This SDK is designed to be compatible with the existing Loops SDKs and follows the same patterns:
- Haskell SDK: Mirrors the data structures and function names
- JavaScript SDK: Similar API design and error handling
- PHP SDK: Comparable class structure and method signatures
Error Handling
The SDK provides comprehensive error handling:
- ValueError: Raised when API key is missing or invalid configuration
- requests.HTTPError: Raised when API calls fail with detailed error messages
- JSON Errors: Handled gracefully with fallback to empty responses
Environment Variables
LOOPS_TOKEN: Your Loops API key (alternative to passing it directly)
Contributing
This is a self-contained module designed to be copied into projects. If you need to modify it:
- Update the
loops_sdk.pyfile - Add corresponding tests in
test_loops_sdk.py - Update this README with any new features or changes
License
This SDK is provided as-is for integration with Loops.so. Please refer to Loops.so's terms of service for API usage guidelines.
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 loops_sdk-0.3.1.tar.gz.
File metadata
- Download URL: loops_sdk-0.3.1.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
675d8b1bb65234da0bf01f72bb42a270c01f1dbf47f1cd0efd855c3961213a72
|
|
| MD5 |
8921b7e476412a273eabd5313fe59845
|
|
| BLAKE2b-256 |
55f0cd70e444abb4e77f68df7132576cb97a7a89efa78034439c67a1717260f6
|
Provenance
The following attestation bundles were made for loops_sdk-0.3.1.tar.gz:
Publisher:
publish.yml on infernal-moose/loops-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loops_sdk-0.3.1.tar.gz -
Subject digest:
675d8b1bb65234da0bf01f72bb42a270c01f1dbf47f1cd0efd855c3961213a72 - Sigstore transparency entry: 245966331
- Sigstore integration time:
-
Permalink:
infernal-moose/loops-python@617cb46da72ce510333dfdfaf5d5024a8393733b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/infernal-moose
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@617cb46da72ce510333dfdfaf5d5024a8393733b -
Trigger Event:
push
-
Statement type:
File details
Details for the file loops_sdk-0.3.1-py3-none-any.whl.
File metadata
- Download URL: loops_sdk-0.3.1-py3-none-any.whl
- Upload date:
- Size: 7.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8ce0a22fa7b6e41cd758e06b18aaad133a602874f6d9a0dec9472f329caa5f5
|
|
| MD5 |
dd4c0f2bd3e945550f6e595e3e34348c
|
|
| BLAKE2b-256 |
5670d56b8f55be925cd4e8958719201c43c1d0b1199c5deb1e1fa199f8f7705d
|
Provenance
The following attestation bundles were made for loops_sdk-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on infernal-moose/loops-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loops_sdk-0.3.1-py3-none-any.whl -
Subject digest:
c8ce0a22fa7b6e41cd758e06b18aaad133a602874f6d9a0dec9472f329caa5f5 - Sigstore transparency entry: 245966332
- Sigstore integration time:
-
Permalink:
infernal-moose/loops-python@617cb46da72ce510333dfdfaf5d5024a8393733b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/infernal-moose
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@617cb46da72ce510333dfdfaf5d5024a8393733b -
Trigger Event:
push
-
Statement type: