Skip to main content

A modern Python SDK for the Pylon customer support API

Project description

py-usepylon-sdk

PyPI version Python versions Tests Coverage License: MIT

A modern, fully-typed Python SDK for the Pylon customer support API.

Features

  • Full API Coverage - Issues, accounts, contacts, messages, webhooks, and more
  • 🔒 Type-safe - Complete type hints with Pydantic v2 models
  • Async Support - Both sync and async clients for maximum flexibility
  • 🔄 Automatic Pagination - Seamlessly iterate through all results
  • 🎯 Filter Builder - Fluent API for building complex queries
  • 🔔 Webhook Handler - Secure webhook signature verification and event routing
  • 🛡️ Robust Error Handling - Detailed exception hierarchy for all error types
  • 🐍 Modern Python - Requires Python 3.11+, uses modern typing syntax

Installation

pip install py-usepylon-sdk

Or with uv:

uv add py-usepylon-sdk

Quick Start

Basic Usage

from pylon import PylonClient

# Initialize the client (uses PYLON_API_KEY env var by default)
with PylonClient(api_key="your-api-key") as client:
    # List recent issues
    for issue in client.issues.list(days=7):
        print(f"#{issue.number}: {issue.title}")

    # Get a specific issue
    issue = client.issues.get("issue_123")
    print(f"Status: {issue.state}")

    # List accounts
    for account in client.accounts.list():
        print(f"Account: {account.name}")

Async Usage

import asyncio
from pylon import AsyncPylonClient

async def main():
    async with AsyncPylonClient(api_key="your-api-key") as client:
        # Iterate through issues asynchronously
        async for issue in client.issues.list(days=7):
            print(f"#{issue.number}: {issue.title}")

        # Get a specific issue
        issue = await client.issues.get("issue_123")
        print(f"Status: {issue.state}")

asyncio.run(main())

Pagination

The SDK handles pagination automatically. Just iterate:

# All pages are fetched automatically as you iterate
for issue in client.issues.list():
    print(issue.title)

# Or collect all results at once
all_issues = client.issues.list().collect()
print(f"Found {len(all_issues)} issues")

Filter Builder

Build complex queries with the fluent filter API:

from pylon.filters import Field, And, Or

# Simple equality filter
issues = client.issues.list(
    filter=Field("state").eq("open")
)

# Complex filters with AND/OR
issues = client.issues.list(
    filter=(
        Field("state").eq("open") &
        Field("priority").gte(3)
    ) | Field("assignee_id").is_null()
)

# Date range filters
from datetime import datetime, timedelta
issues = client.issues.list(
    filter=Field("created_at").between(
        datetime.now() - timedelta(days=30),
        datetime.now()
    )
)

Webhook Handling

Securely handle incoming Pylon webhooks:

from pylon.webhooks import WebhookHandler
from pylon.webhooks.events import IssueNewEvent, IssueAssignedEvent

handler = WebhookHandler(secret="your-webhook-secret")

@handler.on(IssueNewEvent)
def handle_new_issue(event: IssueNewEvent):
    print(f"New issue created: {event.issue_title}")

@handler.on(IssueAssignedEvent)
def handle_assigned(event: IssueAssignedEvent):
    print(f"Issue assigned to: {event.assignee_id}")

@handler.on_any()
def handle_all_events(event):
    print(f"Received event: {event.event_type}")

# In your web framework (Flask example)
@app.route("/webhook", methods=["POST"])
def webhook():
    signature = request.headers.get("X-Pylon-Signature")
    timestamp = request.headers.get("X-Pylon-Timestamp")

    handler.handle(
        payload=request.get_data(),
        signature=signature,
        timestamp=timestamp
    )
    return "OK", 200

Error Handling

The SDK provides a detailed exception hierarchy:

from pylon.exceptions import (
    PylonError,              # Base exception
    PylonAPIError,           # API-related errors
    PylonAuthenticationError,  # 401 - Invalid API key
    PylonNotFoundError,      # 404 - Resource not found
    PylonValidationError,    # 400 - Invalid request
    PylonRateLimitError,     # 429 - Rate limited
    PylonServerError,        # 5xx - Server errors
)

try:
    issue = client.issues.get("nonexistent")
except PylonNotFoundError as e:
    print(f"Issue not found: {e.message}")
except PylonAuthenticationError:
    print("Invalid API key")
except PylonRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except PylonAPIError as e:
    print(f"API error [{e.status_code}]: {e.message}")

Available Resources

Resource Description
client.issues Support tickets and conversations
client.accounts Customer accounts/companies
client.contacts Customer contacts
client.users Team members/agents
client.teams Support teams
client.tags Issue and account tags
client.messages Conversation messages
client.tasks Follow-up tasks
client.projects Customer projects

Development

Setup

# Clone the repository
git clone https://github.com/mgmonteleone/py-usepylon-sdk.git
cd py-usepylon-sdk

# Install with development dependencies
uv sync --all-extras

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=src/pylon --cov-report=term-missing

Linting and Type Checking

uv run ruff check .
uv run mypy src/

Documentation

Documentation is built with MkDocs:

uv run mkdocs serve  # Local development server
uv run mkdocs build  # Build static site

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

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

py_usepylon_sdk-0.5.0.tar.gz (44.5 kB view details)

Uploaded Source

Built Distribution

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

py_usepylon_sdk-0.5.0-py3-none-any.whl (78.4 kB view details)

Uploaded Python 3

File details

Details for the file py_usepylon_sdk-0.5.0.tar.gz.

File metadata

  • Download URL: py_usepylon_sdk-0.5.0.tar.gz
  • Upload date:
  • Size: 44.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for py_usepylon_sdk-0.5.0.tar.gz
Algorithm Hash digest
SHA256 1bc354762dc9a75df71b086c285ff5d4dacd4483d4651791e5dfb7454b90ff00
MD5 3f8057f4a2ae17aa0853040cf039f410
BLAKE2b-256 936894ce249420d68d0b7a6c33032136e73bfcea2e8f2a670730824c011625d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_usepylon_sdk-0.5.0.tar.gz:

Publisher: publish.yml on mgmonteleone/py-usepylon-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_usepylon_sdk-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for py_usepylon_sdk-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a7518098b3cfad3d251b6d6bd90315574c05b2a9d6031fba75878a9c4b146de
MD5 671036fa8447f7612c4fa74e4a5dd05c
BLAKE2b-256 1d747d8e47b98ae884dee87bb7554ccdd6e5f137eaf9ec80b77253138a40932b

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_usepylon_sdk-0.5.0-py3-none-any.whl:

Publisher: publish.yml on mgmonteleone/py-usepylon-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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