Skip to main content

Sage SDK for Python - Customer support ticketing made simple

Project description

Sage Python SDK

The official Python SDK for Sage - Customer support ticketing made simple.

Installation

pip install roselabs-sage

With framework support:

pip install roselabs-sage[fastapi]  # FastAPI/Starlette
pip install roselabs-sage[flask]    # Flask
pip install roselabs-sage[django]   # Django
pip install roselabs-sage[all]      # All frameworks

Quick Start

from sage_sdk import Sage

sage = Sage(api_key="sk_sage_...")

# Create a support ticket
ticket = sage.create_ticket(
    customer_email="user@example.com",
    subject="Help with billing",
    message="I need to update my payment method",
    metadata={"plan": "pro", "user_id": "123"}
)

print(f"Created ticket #{ticket.ticket_number}")
print(f"Portal URL: {ticket.portal_url}")

Features

  • Simple API - Create tickets with a single function call
  • Async Support - Full async/await support for modern Python
  • Framework Integrations - FastAPI, Flask, and Django support
  • Type Hints - Full type annotations for IDE support
  • Fail Fast - Configuration validated at initialization

API Reference

Creating Tickets

from sage_sdk import Sage

sage = Sage(api_key="sk_sage_...")

# Basic ticket
ticket = sage.create_ticket(
    customer_email="user@example.com",
    subject="Can't login",
    message="I forgot my password and reset email isn't arriving",
)

# With priority and metadata
ticket = sage.create_ticket(
    customer_email="user@example.com",
    subject="Urgent: Production down",
    message="Our application is not responding",
    customer_name="Jane Smith",
    priority="urgent",  # low, medium, high, urgent
    metadata={
        "user_id": "u_123",
        "plan": "enterprise",
        "environment": "production",
    }
)

Async Usage

from sage_sdk import Sage

sage = Sage(api_key="sk_sage_...")

async def handle_support_request():
    ticket = await sage.create_ticket_async(
        customer_email="user@example.com",
        subject="Need help",
        message="...",
    )
    return ticket

Identifying Customers

Pre-create or update customer profiles:

customer = sage.identify_customer(
    email="user@example.com",
    name="Jane Smith",
    external_id="cust_123",  # Your internal ID
    company="Acme Corp",
    phone="+1-555-0123",
    metadata={
        "plan": "enterprise",
        "mrr": 299,
        "signup_date": "2024-01-15",
    }
)

Adding Messages

Add messages to existing tickets:

ticket = sage.add_message(
    ticket_id="ticket_abc123",
    message="Here's an update on your issue...",
    sender_type="system",  # customer, agent, or system
)

Module-Level Functions

For simpler usage without managing instances:

from sage_sdk import init, create_ticket

# Initialize once
init(api_key="sk_sage_...")

# Use anywhere
ticket = create_ticket(
    customer_email="user@example.com",
    subject="Help needed",
    message="...",
)

Framework Integrations

FastAPI

from fastapi import FastAPI
from sage_sdk import Sage
from sage_sdk.fastapi import instrument_fastapi

sage = Sage(api_key="sk_sage_...")
app = FastAPI()

# Capture exceptions automatically
instrument_fastapi(app, sage)

# Or with auto-ticket creation
def get_user_email(request):
    return request.state.user.email if hasattr(request.state, 'user') else None

instrument_fastapi(
    app,
    sage,
    create_tickets=True,
    get_customer_email=get_user_email,
)

Flask

from flask import Flask, g
from sage_sdk import Sage
from sage_sdk.flask import init_app

app = Flask(__name__)
sage = Sage(api_key="sk_sage_...")

def get_email():
    return getattr(g, 'user_email', None)

init_app(app, sage, create_tickets=True, get_customer_email=get_email)

Or using app config:

from flask import Flask
from sage_sdk.flask import SageFlask

app = Flask(__name__)
app.config["SAGE_API_KEY"] = "sk_sage_..."

sage_ext = SageFlask(app)

Django

# settings.py
SAGE_API_KEY = "sk_sage_..."
SAGE_CREATE_TICKETS = True  # Auto-create tickets for exceptions

MIDDLEWARE = [
    ...
    'sage_sdk.django.SageMiddleware',
]
# views.py
from sage_sdk.django import get_sage

sage = get_sage()
ticket = sage.create_ticket(...)

Configuration

from sage_sdk import Sage

sage = Sage(
    api_key="sk_sage_...",          # Required
    api_url="https://...",          # Custom API URL (optional)
    timeout=30.0,                   # Request timeout in seconds
    debug=False,                    # Enable debug logging
    default_metadata={              # Included with all tickets
        "app_version": "1.2.3",
        "environment": "production",
    },
)

Configuration Validation

The SDK validates configuration at initialization:

from sage_sdk import Sage, SageConfigError

try:
    sage = Sage(api_key="invalid")
except SageConfigError as e:
    print(e)
    # Invalid Sage configuration:
    #   - api_key must start with 'sk_sage_'

Error Handling

from sage_sdk import Sage, SageAPIError, SageRateLimitError

sage = Sage(api_key="sk_sage_...")

try:
    ticket = sage.create_ticket(...)
except SageRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except SageAPIError as e:
    print(f"API error [{e.status_code}]: {e}")

Context Manager

The client can be used as a context manager:

with Sage(api_key="sk_sage_...") as sage:
    ticket = sage.create_ticket(...)
# Client automatically closed

# Async version
async with Sage(api_key="sk_sage_...") as sage:
    ticket = await sage.create_ticket_async(...)

Types

The SDK provides typed dataclasses:

from sage_sdk import Ticket, Customer, TicketStatus, TicketPriority

ticket: Ticket
ticket.id              # str
ticket.ticket_number   # str (e.g., "T-1234")
ticket.subject         # str
ticket.status          # TicketStatus (open, in_progress, resolved, closed)
ticket.priority        # TicketPriority (low, medium, high, urgent)
ticket.portal_url      # str | None
ticket.messages        # list[TicketMessage]
ticket.metadata        # dict[str, Any]

License

MIT

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

roselabs_sage-0.1.2.tar.gz (56.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

roselabs_sage-0.1.2-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file roselabs_sage-0.1.2.tar.gz.

File metadata

  • Download URL: roselabs_sage-0.1.2.tar.gz
  • Upload date:
  • Size: 56.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for roselabs_sage-0.1.2.tar.gz
Algorithm Hash digest
SHA256 189ae0ddcad4d38b1a8f11de8b4a0125561ecb285166cc13941e65760d0054e2
MD5 05a4c7b5439311014163f7969c91a77e
BLAKE2b-256 c0ba9b0996855bd705084bfe959a93e622ffeacc732f3a096c6e1fa2e465a6db

See more details on using hashes here.

File details

Details for the file roselabs_sage-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: roselabs_sage-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for roselabs_sage-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cb7aff0cabfb370c6f6ec6226cdbe8acbe26e6385960fade61c192a297065268
MD5 11bd6a4c875ab28b6d6983d821b9bb0f
BLAKE2b-256 eee866cb9431b99c1f4f93c5317fe9072a2f8aa854409b14840ec8fd809b35d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page