Vortex Python SDK for invitation management and JWT generation
Project description
Vortex Python SDK
A Python SDK for Vortex invitation management and JWT generation.
Features
Invitation Delivery Types
Vortex supports multiple delivery methods for invitations:
email- Email invitations sent by Vortex (includes reminders and nudges)phone- Phone invitations sent by the user/customershare- Shareable invitation links for social sharinginternal- Internal invitations managed entirely by your application- No email/SMS communication triggered by Vortex
- Target value can be any customer-defined identifier
- Useful for in-app invitation flows where you handle the delivery
- Example use case: In-app notifications, dashboard invites, etc.
Installation
pip install vortex-python-sdk
Note: The package will be available on PyPI once published. See PUBLISHING.md for publishing instructions.
Usage
Basic Setup
from vortex_sdk import Vortex
# Initialize the client with your Vortex API key
vortex = Vortex(api_key="your-vortex-api-key")
# Or with custom base URL
vortex = Vortex(api_key="your-vortex-api-key", base_url="https://custom-api.example.com")
JWT Generation
# Generate JWT for a user
user = {
"id": "user-123",
"email": "user@example.com",
"user_name": "Jane Doe", # Optional: user's display name
"user_avatar_url": "https://example.com/avatars/jane.jpg", # Optional: user's avatar URL
"admin_scopes": ["autojoin"] # Optional: grants autojoin admin privileges
}
jwt = vortex.generate_jwt(user=user)
print(f"JWT: {jwt}")
# Or using type-safe models
from vortex_sdk import User
user = User(
id="user-123",
email="user@example.com",
user_name="Jane Doe", # Optional
user_avatar_url="https://example.com/avatars/jane.jpg", # Optional
admin_scopes=["autojoin"] # Optional
)
jwt = vortex.generate_jwt(user=user)
Invitation Management
Get Invitations by Target
import asyncio
async def get_user_invitations():
# Async version
invitations = await vortex.get_invitations_by_target("email", "user@example.com")
for invitation in invitations:
print(f"Invitation ID: {invitation.id}, Status: {invitation.status}")
# Sync version
invitations = vortex.get_invitations_by_target_sync("email", "user@example.com")
Accept an Invitation
async def accept_user_invitation():
# Async version
result = await vortex.accept_invitation(
invitation_id="inv-123",
user={"email": "user@example.com"}
)
print(f"Result: {result}")
# Sync version
result = vortex.accept_invitation_sync(
invitation_id="inv-123",
user={"email": "user@example.com"}
)
Get Specific Invitation
async def get_invitation():
# Async version
invitation = await vortex.get_invitation("invitation-id")
print(f"Invitation: {invitation.id}")
# Sync version
invitation = vortex.get_invitation_sync("invitation-id")
Revoke Invitation
async def revoke_invitation():
# Async version
result = await vortex.revoke_invitation("invitation-id")
print(f"Revoked: {result}")
# Sync version
result = vortex.revoke_invitation_sync("invitation-id")
Group Operations
Get Invitations by Group
async def get_group_invitations():
# Async version
invitations = await vortex.get_invitations_by_group("organization", "org123")
print(f"Found {len(invitations)} invitations")
# Sync version
invitations = vortex.get_invitations_by_group_sync("organization", "org123")
Delete Invitations by Group
async def delete_group_invitations():
# Async version
result = await vortex.delete_invitations_by_group("organization", "org123")
print(f"Deleted: {result}")
# Sync version
result = vortex.delete_invitations_by_group_sync("organization", "org123")
Reinvite
async def reinvite_user():
# Async version
invitation = await vortex.reinvite("invitation-id")
print(f"Reinvited: {invitation.id}")
# Sync version
invitation = vortex.reinvite_sync("invitation-id")
Sync Internal Invitation
If you're using internal delivery type invitations and managing the invitation flow within your own application, you can sync invitation decisions back to Vortex when users accept or decline invitations in your system.
async def sync_internal_invitation_action():
# Async version
result = await vortex.sync_internal_invitation(
creator_id="user-123", # The inviter's user ID in your system
target_value="user-456", # The invitee's user ID in your system
action="accepted", # "accepted" or "declined"
component_id="component-uuid" # The widget component UUID
)
print(f"Processed: {result['processed']}")
print(f"Invitation IDs: {result['invitationIds']}")
# Sync version
result = vortex.sync_internal_invitation_sync(
creator_id="user-123",
target_value="user-456",
action="accepted",
component_id="component-uuid"
)
Parameters:
creator_id(str) — The inviter's user ID in your systemtarget_value(str) — The invitee's user ID in your systemaction("accepted" | "declined") — The invitation decisioncomponent_id(str) — The widget component UUID
Response:
processed(int) — Count of invitations processedinvitationIds(list[str]) — IDs of processed invitations
Use cases:
- You handle invitation delivery through your own in-app notifications or UI
- Users accept/decline invitations within your application
- You need to keep Vortex updated with the invitation status
Context Manager Usage
# Async context manager
async with Vortex(api_key="your-api-key") as vortex:
invitations = await vortex.get_invitations_by_target("email", "user@example.com")
# Sync context manager
with Vortex(api_key="your-api-key") as vortex:
invitations = vortex.get_invitations_by_target_sync("email", "user@example.com")
Error Handling
from vortex_sdk import VortexApiError
try:
invitation = vortex.get_invitation_sync("invalid-id")
except VortexApiError as e:
print(f"API Error: {e.message} (Status: {e.status_code})")
except Exception as e:
print(f"Unexpected error: {e}")
Development
Installation
# Install development dependencies
pip install -e ".[dev]"
Running Tests
pytest
Code Formatting
# Format code
black src/ tests/
isort src/ tests/
# Lint code
ruff check src/ tests/
mypy src/
Webhooks
The SDK provides built-in support for verifying and parsing incoming webhook events from Vortex.
Setup
import os
from vortex_sdk import VortexWebhooks, is_webhook_event, is_analytics_event
webhooks = VortexWebhooks(secret=os.environ["VORTEX_WEBHOOK_SECRET"])
Verifying and Parsing Events
# In your HTTP handler (Flask example):
@app.route("/webhooks/vortex", methods=["POST"])
def handle_webhook():
payload = request.get_data(as_text=True)
signature = request.headers.get("X-Vortex-Signature", "")
try:
event = webhooks.construct_event(payload, signature)
except VortexWebhookSignatureError:
return "Invalid signature", 400
if is_webhook_event(event.__dict__):
print(f"Webhook event: {event.type}")
elif is_analytics_event(event.__dict__):
print(f"Analytics event: {event.name}")
return "OK", 200
Event Types
Webhook event types are available as the WebhookEventType enum:
from vortex_sdk import WebhookEventType
if event.type == WebhookEventType.INVITATION_ACCEPTED:
# Handle invitation accepted
pass
License
MIT
Project details
Release history Release notifications | RSS feed
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 vortex_python_sdk-0.10.0.tar.gz.
File metadata
- Download URL: vortex_python_sdk-0.10.0.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b237933ebc2ac09504de043180bbfddc616c54c77702b14d4d0aea262793b650
|
|
| MD5 |
8ed12ebed13048e951b7344f21c52cb3
|
|
| BLAKE2b-256 |
86f5e09a3d49b53d88a3f8ef0bd3cd317645debed2a8fd8c0e2635dc8aad6c8f
|
File details
Details for the file vortex_python_sdk-0.10.0-py3-none-any.whl.
File metadata
- Download URL: vortex_python_sdk-0.10.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50e1f444a773448b496954a04ad9fd70e7fd2714e82c310f0aebcebb8f7fb154
|
|
| MD5 |
90ab7d9a1320bd1fb79ab26a35c1071e
|
|
| BLAKE2b-256 |
859e68ca9f871727c8ed8a870ee7c74c76b520bdc055cdef4759b7e7e294591e
|