Modern Python SDK for Zendesk API
Project description
Python Zendesk SDK
Modern Python SDK for Zendesk API with async support, full type safety, and comprehensive error handling.
Features
- Async HTTP Client: Built on httpx with retry logic, rate limiting, and exponential backoff
- Type Safety: Full Pydantic v2 models for Users, Organizations, Tickets, and Comments
- Pagination: Both offset-based and cursor-based pagination support
- Search: Zendesk search API support
- Configuration: Flexible configuration with environment variable support
Installation
pip install python-zendesk-sdk
Quick Start
import asyncio
from zendesk_sdk import ZendeskClient, ZendeskConfig
async def main():
config = ZendeskConfig(
subdomain="your-subdomain",
email="your-email@example.com",
token="your-api-token",
)
async with ZendeskClient(config) as client:
# Get users with pagination
users_paginator = await client.get_users(per_page=10)
users = await users_paginator.get_page()
for user in users:
print(f"User: {user.name} ({user.email})")
# Get specific ticket
ticket = await client.get_ticket(ticket_id=12345)
print(f"Ticket: {ticket.subject}")
# Search tickets
results = await client.search_tickets("status:open priority:high")
for ticket in results:
print(f"High priority: {ticket.subject}")
asyncio.run(main())
Configuration
Direct instantiation
config = ZendeskConfig(
subdomain="mycompany",
email="user@example.com",
token="api_token_here"
)
Environment variables
export ZENDESK_SUBDOMAIN=mycompany
export ZENDESK_EMAIL=user@example.com
export ZENDESK_TOKEN=api_token_here
config = ZendeskConfig() # Will load from environment
API Methods
Users
get_users()- List users with paginationget_user(user_id)- Get user by IDget_user_by_email(email)- Get user by email
Organizations
get_organizations()- List organizations with paginationget_organization(organization_id)- Get organization by ID
Tickets
get_tickets()- List tickets with paginationget_ticket(ticket_id)- Get ticket by IDget_user_tickets(user_id)- Get tickets for a userget_organization_tickets(organization_id)- Get tickets for an organization
Enriched Tickets
Load tickets with all related data (comments + users) in minimum API requests:
get_enriched_ticket(ticket_id)- Get ticket with comments and all userssearch_enriched_tickets(query)- Search tickets with all related dataget_organization_enriched_tickets(org_id)- Get organization tickets with all dataget_user_enriched_tickets(user_id)- Get user tickets with all data
# Get ticket with all related data
enriched = await client.get_enriched_ticket(12345)
print(f"Ticket: {enriched.ticket.subject}")
print(f"Requester: {enriched.requester.name}")
print(f"Assignee: {enriched.assignee.name if enriched.assignee else 'Unassigned'}")
for comment in enriched.comments:
author = enriched.get_comment_author(comment)
print(f"Comment by {author.name}: {comment.body[:50]}...")
# Search with all data loaded
results = await client.search_enriched_tickets("status:open")
for item in results:
print(f"{item.ticket.subject} - {len(item.comments)} comments")
Comments
get_ticket_comments(ticket_id)- Get comments for a ticketadd_ticket_comment(ticket_id, body, public=False)- Add a comment (private by default)make_comment_private(ticket_id, comment_id)- Convert public comment to internal noteredact_comment_string(ticket_id, comment_id, text)- Permanently redact text from comment
Tags
get_ticket_tags(ticket_id)- Get all tags for a ticketadd_ticket_tags(ticket_id, tags)- Add tags without removing existing onesset_ticket_tags(ticket_id, tags)- Replace all tags with a new setremove_ticket_tags(ticket_id, tags)- Remove specific tags
# Get current tags
tags = await client.get_ticket_tags(12345)
# ["billing", "urgent"]
# Add new tags (keeps existing)
tags = await client.add_ticket_tags(12345, ["vip"])
# ["billing", "urgent", "vip"]
# Replace all tags
tags = await client.set_ticket_tags(12345, ["support", "priority"])
# ["support", "priority"]
# Remove specific tags
tags = await client.remove_ticket_tags(12345, ["priority"])
# ["support"]
Attachments
download_attachment(content_url)- Download attachment content as bytesupload_attachment(data, filename, content_type)- Upload file and get token
# Download an attachment from a comment
comments = await client.get_ticket_comments(12345)
for comment in comments:
for attachment in comment.attachments or []:
content = await client.download_attachment(attachment.content_url)
with open(attachment.file_name, "wb") as f:
f.write(content)
# Upload a file and attach to a comment
with open("screenshot.png", "rb") as f:
token = await client.upload_attachment(
f.read(),
"screenshot.png",
"image/png"
)
await client.add_ticket_comment(
ticket_id=12345,
body="See attached screenshot",
uploads=[token]
)
Search
search(query)- General searchsearch_users(query)- Search userssearch_tickets(query)- Search ticketssearch_organizations(query)- Search organizations
Error Handling
The SDK provides specific exception classes for different error types:
from zendesk_sdk.exceptions import (
ZendeskAuthException,
ZendeskHTTPException,
ZendeskRateLimitException,
ZendeskTimeoutException,
ZendeskValidationException,
)
async with ZendeskClient(config) as client:
try:
user = await client.get_user(user_id=12345)
except ZendeskAuthException as e:
# 401/403 - Authentication failed
print(f"Auth error: {e.message}")
except ZendeskRateLimitException as e:
# 429 - Rate limit exceeded
print(f"Rate limited, retry after: {e.retry_after}s")
except ZendeskHTTPException as e:
# Other HTTP errors (404, 500, etc.)
print(f"HTTP {e.status_code}: {e.message}")
except ZendeskTimeoutException as e:
# Request timeout
print(f"Timeout: {e.message}")
Automatic Retry
The SDK automatically retries on:
- Rate limiting (429) - with respect to
Retry-Afterheader - Server errors (5xx) - with exponential backoff
- Network errors and timeouts
Configure retry behavior:
config = ZendeskConfig(
subdomain="mycompany",
email="user@example.com",
token="api_token",
timeout=30.0, # Request timeout in seconds
max_retries=3, # Number of retry attempts
)
Examples
See the examples/ directory for complete usage examples:
basic_usage.py- Basic configuration and API operationspagination_example.py- Working with paginated resultserror_handling.py- Error handling patternsenriched_tickets.py- Loading tickets with related data
Requirements
- Python 3.8+
- httpx
- pydantic >=2.0
License
MIT License
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 python_zendesk_sdk-0.1.2.tar.gz.
File metadata
- Download URL: python_zendesk_sdk-0.1.2.tar.gz
- Upload date:
- Size: 40.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a8f7be857e47775e438d8448de9c1ae85645a56ab9b4046e9398a10c8fbb67d
|
|
| MD5 |
9f7ef7cdf9ed20e8b0cfbb05a8151ce9
|
|
| BLAKE2b-256 |
c046427cdcf17fff6bff72c8ec68e0ec80c9864853b20d011896713e3299eaef
|
Provenance
The following attestation bundles were made for python_zendesk_sdk-0.1.2.tar.gz:
Publisher:
publish.yml on bormog/python-zendesk-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_zendesk_sdk-0.1.2.tar.gz -
Subject digest:
2a8f7be857e47775e438d8448de9c1ae85645a56ab9b4046e9398a10c8fbb67d - Sigstore transparency entry: 788461176
- Sigstore integration time:
-
Permalink:
bormog/python-zendesk-sdk@76bc6a5dd8df9f9b47cc2acf756ded229559673f -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/bormog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@76bc6a5dd8df9f9b47cc2acf756ded229559673f -
Trigger Event:
release
-
Statement type:
File details
Details for the file python_zendesk_sdk-0.1.2-py3-none-any.whl.
File metadata
- Download URL: python_zendesk_sdk-0.1.2-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b44a4158a6fe0d1e2cab3fa43371fef88bda4f646e0aa7c99abe9d2093505c8
|
|
| MD5 |
807bdc54ba20cd3caba9364e9030da81
|
|
| BLAKE2b-256 |
7bca7d9a768fb033106f3a3ce4f0bc34e83a3899cb36d27649a7b448a85db2c8
|
Provenance
The following attestation bundles were made for python_zendesk_sdk-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on bormog/python-zendesk-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_zendesk_sdk-0.1.2-py3-none-any.whl -
Subject digest:
1b44a4158a6fe0d1e2cab3fa43371fef88bda4f646e0aa7c99abe9d2093505c8 - Sigstore transparency entry: 788461197
- Sigstore integration time:
-
Permalink:
bormog/python-zendesk-sdk@76bc6a5dd8df9f9b47cc2acf756ded229559673f -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/bormog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@76bc6a5dd8df9f9b47cc2acf756ded229559673f -
Trigger Event:
release
-
Statement type: