Skip to main content

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:

TierRequests/DayRequests/Minute
Free1,00010
Professional100,000100
Enterprise1,000,0001,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​


Last Updated: October 13, 2025