Python SDK
Official Python SDK for the Torvus Security Platform API.
Package: torvus-sdk
Version: v0.1.0-alpha (Foundation Complete)
Repository: github.com/torvus-security/torvus
Installationā
pip install torvus-sdk
Or with development dependencies:
pip install torvus-sdk[dev]
Requirements: Python 3.8+
Quick Startā
from torvus_sdk import TorvusClient
# Initialize client with your API key
client = TorvusClient(api_key="sk_live_your_api_key_here")
# Create a vault
vault = client.post("/v1/vaults", {
"name": "Personal Documents",
"description": "Important files",
"check_in_frequency": "weekly",
})
print(f"Vault created with ID: {vault['id']}")
# Get all vaults
vaults = client.get("/v1/vaults")
print(f"You have {len(vaults['data'])} vaults")
# Update vault
client.patch(f"/v1/vaults/{vault['id']}", {
"name": "Updated Name",
})
# Delete vault
client.delete(f"/v1/vaults/{vault['id']}")
Authenticationā
The SDK requires an API key which you can generate in your API Keys dashboard.
# Method 1: Pass API key directly
from torvus_sdk import TorvusClient
client = TorvusClient(api_key="sk_live_your_api_key_here")
# Method 2: Use environment variable (recommended)
import os
from torvus_sdk import TorvusClient
client = TorvusClient(api_key=os.getenv("TORVUS_API_KEY"))
Best Practice: Store your API key in an environment variable:
export TORVUS_API_KEY="sk_live_your_api_key_here"
Configurationā
from torvus_sdk import TorvusClient
client = TorvusClient(
# Required: Your API key
api_key="sk_live_your_api_key_here",
# Optional: Override base URL (default: https://api.torvussecurity.com)
base_url="https://api.torvussecurity.com",
# Optional: Request timeout in seconds (default: 30)
timeout=30,
# Optional: Max retries for 5xx errors (default: 3)
max_retries=3,
# Optional: Enable debug logging (default: False)
debug=False,
# Optional: Custom headers for all requests
headers={
"X-Custom-Header": "value",
},
)
Making Requestsā
The SDK provides convenience methods for all HTTP verbs:
GET Requestā
# List vaults
vaults = client.get("/v1/vaults")
# Get specific vault
vault = client.get("/v1/vaults/vault_123")
# With query parameters
vaults = client.get("/v1/vaults", params={
"limit": 10,
"offset": 0,
})
POST Requestā
# Create vault
vault = client.post("/v1/vaults", {
"name": "Personal Documents",
"check_in_frequency": "weekly",
})
# Add recipient
recipient = client.post("/v1/recipients", {
"email": "recipient@example.com",
"name": "John Doe",
"relationship": "spouse",
})
PATCH Requestā
# Update vault
updated = client.patch("/v1/vaults/vault_123", {
"name": "Updated Name",
"description": "Updated description",
})
PUT Requestā
# Replace vault (full update)
replaced = client.put("/v1/vaults/vault_123", {
"name": "Completely Replaced",
"check_in_frequency": "monthly",
"description": "New description",
})
DELETE Requestā
# Delete vault
client.delete("/v1/vaults/vault_123")
# Delete document
client.delete("/v1/documents/doc_456")
Error Handlingā
from torvus_sdk import TorvusClient, TorvusApiError
import os
client = TorvusClient(api_key=os.getenv("TORVUS_API_KEY"))
try:
vault = client.get("/v1/vaults/invalid_id")
except TorvusApiError as error:
# Handle specific error types
if error.is_authentication_error():
print("Invalid API key")
elif error.is_not_found_error():
print("Vault not found")
elif error.is_rate_limit_error():
retry_after = error.details.get("retryAfter")
print(f"Rate limited. Retry after: {retry_after} seconds")
elif error.is_server_error():
print("Server error, please try again")
else:
print(f"API error: {error.message} ({error.error_code})")
# Access error details
print(f"Status code: {error.status_code}")
print(f"Error code: {error.error_code}")
print(f"Request ID: {error.request_id}")
print(f"Details: {error.details}")
Error Type Helpersā
The TorvusApiError class provides helper methods for common error types:
error.is_authentication_error() # 401 - Invalid API key
error.is_authorization_error() # 403 - Insufficient permissions
error.is_not_found_error() # 404 - Resource not found
error.is_rate_limit_error() # 429 - Rate limit exceeded
error.is_server_error() # 5xx - Server error
error.is_client_error() # 4xx - Client error
Automatic Retry Logicā
The SDK automatically retries requests that fail with 5xx server errors using exponential backoff:
- Retry attempts: 3 by default (configurable via
max_retries) - Backoff strategy: Exponential (1s, 2s, 4s, 8s, etc.)
- Retried status codes: 500, 501, 502, 503, 504
# Configure custom retry behavior
client = TorvusClient(
api_key=os.getenv("TORVUS_API_KEY"),
max_retries=5, # Retry up to 5 times
)
Note: 4xx client errors (except 429 rate limits) are not retried, as these typically indicate incorrect request data.
Debug Loggingā
Enable debug mode to log all requests and responses:
client = TorvusClient(
api_key=os.getenv("TORVUS_API_KEY"),
debug=True, # Logs all requests, responses, and retries
)
# Console output example:
# [Torvus SDK] POST https://api.torvussecurity.com/v1/vaults
# [Torvus SDK] Request body: {'name': 'Test Vault'}
# [Torvus SDK] Response 201 from https://api.torvussecurity.com/v1/vaults
# [Torvus SDK] Retry attempt 1/3 for GET /v1/vaults/vault_123
Context Managerā
Use the client as a context manager for automatic cleanup:
from torvus_sdk import TorvusClient
import os
with TorvusClient(api_key=os.getenv("TORVUS_API_KEY")) as client:
vault = client.get("/v1/vaults/vault_123")
print(f"Vault: {vault['name']}")
# Session automatically closed
Advanced Usageā
Access Underlying Requests Sessionā
For advanced use cases, access the underlying requests session:
# Access the session
session = client.session
# Add custom headers
session.headers["X-Custom-Header"] = "value"
# Configure connection pooling
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
adapter = HTTPAdapter(
pool_connections=10,
pool_maxsize=20,
)
session.mount("https://", adapter)
Type Hintsā
The SDK is fully type-hinted and works great with mypy and other type checkers:
from typing import Any, Dict
from torvus_sdk import TorvusClient
import os
client: TorvusClient = TorvusClient(api_key=os.getenv("TORVUS_API_KEY"))
# Type hints for request data
vault_data: Dict[str, Any] = {
"name": "Personal Documents",
"check_in_frequency": "weekly",
}
vault: Dict[str, Any] = client.post("/v1/vaults", vault_data)
Complete Exampleā
Here's a complete example demonstrating a typical workflow:
#!/usr/bin/env python3
"""
Example script demonstrating Torvus SDK usage
"""
import os
from torvus_sdk import TorvusClient, TorvusApiError
def main():
# Initialize client
client = TorvusClient(
api_key=os.getenv("TORVUS_API_KEY"),
debug=False,
)
try:
# 1. Create a vault
print("Creating vault...")
vault = client.post("/v1/vaults", {
"name": "Family Documents",
"description": "Important family files",
"check_in_frequency": "monthly",
})
print(f"ā Vault created: {vault['id']}")
# 2. Add a recipient
print("Adding recipient...")
recipient = client.post("/v1/recipients", {
"email": "recipient@example.com",
"name": "Jane Doe",
"relationship": "spouse",
})
print(f"ā Recipient added: {recipient['id']}")
# 3. List all vaults
print("Fetching vaults...")
vaults = client.get("/v1/vaults")
print(f"ā Found {len(vaults['data'])} vaults")
# 4. Update vault
print("Updating vault...")
updated = client.patch(f"/v1/vaults/{vault['id']}", {
"description": "Updated description",
})
print(f"ā Vault updated: {updated['name']}")
# 5. Check in
print("Performing check-in...")
checkin = client.post("/v1/check-ins", {
"vault_id": vault["id"],
})
print(f"ā Check-in completed. Next: {checkin['next_check_in']}")
print("\nā
All operations completed successfully!")
except TorvusApiError as error:
print(f"ā API Error: {error.message}")
print(f" Status: {error.status_code}")
print(f" Code: {error.error_code}")
print(f" Request ID: {error.request_id}")
exit(1)
except Exception as error:
print(f"ā Unexpected error: {error}")
exit(1)
if __name__ == "__main__":
main()
Environment Variablesā
The SDK respects the following environment variables:
# API key (alternative to passing in constructor)
export TORVUS_API_KEY=sk_live_your_api_key_here
# API base URL (for testing/development)
export TORVUS_API_BASE_URL=https://api-sandbox.torvussecurity.com
Rate Limitingā
The API enforces rate limits based on your tier:
| Tier | Requests/Day | Requests/Minute |
|---|---|---|
| Free | 1,000 | 10 |
| Professional | 100,000 | 100 |
| Enterprise | 1,000,000 | 1,000 |
When rate limited (HTTP 429), the SDK throws a TorvusApiError with is_rate_limit_error() returning True. The error details include a retryAfter field indicating seconds to wait.
Example: Handle rate limiting with exponential backoff:
import time
from typing import Callable, TypeVar
from torvus_sdk import TorvusClient, TorvusApiError
T = TypeVar('T')
def with_rate_limit_retry(
fn: Callable[[], T],
max_retries: int = 3
) -> T:
"""Execute function with rate limit retry logic"""
for i in range(max_retries):
try:
return fn()
except TorvusApiError as error:
if error.is_rate_limit_error():
retry_after = error.details.get("retryAfter", 1)
print(f"Rate limited. Waiting {retry_after}s before retry...")
time.sleep(retry_after)
else:
raise error
raise Exception("Max retry attempts exceeded")
# Usage
client = TorvusClient(api_key=os.getenv("TORVUS_API_KEY"))
vaults = with_rate_limit_retry(lambda: client.get("/v1/vaults"))
Testingā
Unit Testingā
For unit testing, you can mock the SDK using unittest.mock or pytest-mock:
from unittest.mock import Mock, patch
from torvus_sdk import TorvusClient
def test_create_vault():
# Create mock client
mock_client = Mock(spec=TorvusClient)
mock_client.post.return_value = {
"id": "vault_test123",
"name": "Test Vault",
}
# Use mock client
result = mock_client.post("/v1/vaults", {"name": "Test Vault"})
# Assertions
assert result["id"] == "vault_test123"
mock_client.post.assert_called_once_with(
"/v1/vaults",
{"name": "Test Vault"}
)
Pytest Exampleā
import pytest
from torvus_sdk import TorvusClient, TorvusApiError
@pytest.fixture
def client():
return TorvusClient(api_key="test_key")
def test_client_initialization():
client = TorvusClient(api_key="test_key")
assert client.api_key == "test_key"
assert client.base_url == "https://api.torvussecurity.com"
def test_error_handling(client):
with pytest.raises(TorvusApiError) as exc_info:
# Trigger error (would need mocking in real test)
client.get("/v1/invalid")
error = exc_info.value
assert error.is_client_error()
Virtual Environmentsā
Recommended: Always use virtual environments for Python projects:
# Create virtual environment
python -m venv venv
# Activate (Linux/macOS)
source venv/bin/activate
# Activate (Windows)
venv\Scripts\activate
# Install SDK
pip install torvus-sdk
# Deactivate when done
deactivate
Troubleshootingā
Import Errorsā
If you encounter import errors, ensure the SDK is installed:
pip install --upgrade torvus-sdk
SSL Certificate Errorsā
If you encounter SSL errors, update your certifi package:
pip install --upgrade certifi
Type Checking with mypyā
To enable type checking, install mypy:
pip install mypy
mypy your_script.py
The SDK includes a py.typed marker for PEP 561 compliance.
Roadmapā
v0.1.0 (Current)ā
- ā Core HTTP client with error handling
- ā Automatic retries with exponential backoff
- ā Full type hints (PEP 484)
- ā Debug logging
- ā Context manager support
v0.2.0 (Planned)ā
- ā³ High-level resource methods (e.g.,
client.vaults.create()) - ā³ Pagination helper utilities
- ā³ Webhook signature verification
- ā³ File upload/download helpers
- ā³ Request caching
- ā³ Rate limit tracking
- ā³ Async/await support
v1.0.0 (Stable Release)ā
- ā³ Production-ready with 100% test coverage
- ā³ Complete OpenAPI coverage
- ā³ Performance benchmarks
- ā³ Comprehensive documentation
Supportā
- Documentation: docs.torvussecurity.com
- API Reference: API Endpoints
- GitHub Issues: Report a bug
- Email: support@torvussecurity.com
Last Updated: October 13, 2025