python-zendesk-sdk 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/PKG-INFO +82 -2
  2. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/README.md +81 -1
  3. python_zendesk_sdk-0.1.3/examples/help_center.py +141 -0
  4. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/pyproject.toml +1 -1
  5. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/__init__.py +9 -2
  6. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/client.py +33 -0
  7. python_zendesk_sdk-0.1.3/src/zendesk_sdk/help_center_client.py +528 -0
  8. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/__init__.py +5 -0
  9. python_zendesk_sdk-0.1.3/src/zendesk_sdk/models/help_center.py +88 -0
  10. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/pagination.py +59 -0
  11. python_zendesk_sdk-0.1.3/tests/test_help_center_client.py +571 -0
  12. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/.flake8 +0 -0
  13. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/.github/workflows/publish.yml +0 -0
  14. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/.gitignore +0 -0
  15. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/.python-version +0 -0
  16. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/LICENSE +0 -0
  17. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/examples/basic_usage.py +0 -0
  18. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/examples/enriched_tickets.py +0 -0
  19. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/examples/error_handling.py +0 -0
  20. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/examples/pagination_example.py +0 -0
  21. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/config.py +0 -0
  22. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/exceptions.py +0 -0
  23. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/http_client.py +0 -0
  24. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/base.py +0 -0
  25. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/comment.py +0 -0
  26. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/enriched_ticket.py +0 -0
  27. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/organization.py +0 -0
  28. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/ticket.py +0 -0
  29. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/src/zendesk_sdk/models/user.py +0 -0
  30. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/__init__.py +0 -0
  31. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_client.py +0 -0
  32. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_config.py +0 -0
  33. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_exceptions.py +0 -0
  34. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_http_client.py +0 -0
  35. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_models.py +0 -0
  36. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_package_import.py +0 -0
  37. {python_zendesk_sdk-0.1.2 → python_zendesk_sdk-0.1.3}/tests/test_pagination.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-zendesk-sdk
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Modern Python SDK for Zendesk API
5
5
  Project-URL: Homepage, https://github.com/bormog/python-zendesk-sdk
6
6
  Project-URL: Repository, https://github.com/bormog/python-zendesk-sdk
@@ -42,7 +42,8 @@ Modern Python SDK for Zendesk API with async support, full type safety, and comp
42
42
  ## Features
43
43
 
44
44
  - **Async HTTP Client**: Built on httpx with retry logic, rate limiting, and exponential backoff
45
- - **Type Safety**: Full Pydantic v2 models for Users, Organizations, Tickets, and Comments
45
+ - **Type Safety**: Full Pydantic v2 models for Users, Organizations, Tickets, Comments, and Help Center
46
+ - **Help Center**: Full CRUD for Categories, Sections, and Articles
46
47
  - **Pagination**: Both offset-based and cursor-based pagination support
47
48
  - **Search**: Zendesk search API support
48
49
  - **Configuration**: Flexible configuration with environment variable support
@@ -216,6 +217,84 @@ await client.add_ticket_comment(
216
217
  - `search_tickets(query)` - Search tickets
217
218
  - `search_organizations(query)` - Search organizations
218
219
 
220
+ ### Help Center
221
+
222
+ Access Help Center (Guide) via `client.help_center` namespace:
223
+
224
+ #### Categories
225
+ - `get_categories()` - List categories with pagination
226
+ - `get_category(category_id)` - Get category by ID
227
+ - `create_category(name, description, position)` - Create category
228
+ - `update_category(category_id, ...)` - Update category
229
+ - `delete_category(category_id, force=True)` - Delete category (cascade deletes sections/articles)
230
+
231
+ #### Sections
232
+ - `get_sections()` - List all sections with pagination
233
+ - `get_category_sections(category_id)` - List sections in a category
234
+ - `get_section(section_id)` - Get section by ID
235
+ - `create_section(category_id, name, description, position)` - Create section
236
+ - `update_section(section_id, ...)` - Update section
237
+ - `delete_section(section_id, force=True)` - Delete section (cascade deletes articles)
238
+
239
+ #### Articles
240
+ - `get_articles()` - List all articles with pagination
241
+ - `get_section_articles(section_id)` - List articles in a section
242
+ - `get_category_articles(category_id)` - List articles in a category
243
+ - `get_article(article_id)` - Get article by ID
244
+ - `create_article(section_id, title, body, ...)` - Create article
245
+ - `update_article(article_id, ...)` - Update article
246
+ - `delete_article(article_id)` - Delete article
247
+ - `search_articles(query, ...)` - Full-text search with snippets
248
+
249
+ ```python
250
+ async with ZendeskClient(config) as client:
251
+ hc = client.help_center
252
+
253
+ # Create category -> section -> article hierarchy
254
+ category = await hc.create_category(
255
+ name="Product Documentation",
256
+ description="Help articles for our product"
257
+ )
258
+
259
+ section = await hc.create_section(
260
+ category_id=category.id,
261
+ name="Getting Started"
262
+ )
263
+
264
+ article = await hc.create_article(
265
+ section_id=section.id,
266
+ title="Installation Guide",
267
+ body="<h1>Installation</h1><p>Follow these steps...</p>",
268
+ permission_group_id=252606, # Required
269
+ draft=False, # Publish immediately
270
+ label_names=["installation", "guide"],
271
+ )
272
+
273
+ # Search articles (useful for AI assistants)
274
+ results = await hc.search_articles("password reset")
275
+ for article in results:
276
+ print(f"{article.title}")
277
+ print(f"Snippet: {article.snippet}") # Matching text with <em> tags
278
+
279
+ # Paginate through all articles
280
+ paginator = await hc.get_articles(per_page=50)
281
+ async for article_data in paginator:
282
+ print(article_data["title"])
283
+
284
+ # Update article
285
+ await hc.update_article(
286
+ article.id,
287
+ title="Updated Title",
288
+ promoted=True,
289
+ label_names=["updated", "featured"],
290
+ )
291
+
292
+ # Cascade delete (removes category + all sections + all articles)
293
+ await hc.delete_category(category.id, force=True)
294
+ ```
295
+
296
+ > **Note**: `delete_category()` and `delete_section()` require `force=True` as a safety measure since they cascade delete all child content.
297
+
219
298
  ## Error Handling
220
299
 
221
300
  The SDK provides specific exception classes for different error types:
@@ -271,6 +350,7 @@ See the `examples/` directory for complete usage examples:
271
350
  - `pagination_example.py` - Working with paginated results
272
351
  - `error_handling.py` - Error handling patterns
273
352
  - `enriched_tickets.py` - Loading tickets with related data
353
+ - `help_center.py` - Help Center categories, sections, and articles
274
354
 
275
355
  ## Requirements
276
356
 
@@ -5,7 +5,8 @@ Modern Python SDK for Zendesk API with async support, full type safety, and comp
5
5
  ## Features
6
6
 
7
7
  - **Async HTTP Client**: Built on httpx with retry logic, rate limiting, and exponential backoff
8
- - **Type Safety**: Full Pydantic v2 models for Users, Organizations, Tickets, and Comments
8
+ - **Type Safety**: Full Pydantic v2 models for Users, Organizations, Tickets, Comments, and Help Center
9
+ - **Help Center**: Full CRUD for Categories, Sections, and Articles
9
10
  - **Pagination**: Both offset-based and cursor-based pagination support
10
11
  - **Search**: Zendesk search API support
11
12
  - **Configuration**: Flexible configuration with environment variable support
@@ -179,6 +180,84 @@ await client.add_ticket_comment(
179
180
  - `search_tickets(query)` - Search tickets
180
181
  - `search_organizations(query)` - Search organizations
181
182
 
183
+ ### Help Center
184
+
185
+ Access Help Center (Guide) via `client.help_center` namespace:
186
+
187
+ #### Categories
188
+ - `get_categories()` - List categories with pagination
189
+ - `get_category(category_id)` - Get category by ID
190
+ - `create_category(name, description, position)` - Create category
191
+ - `update_category(category_id, ...)` - Update category
192
+ - `delete_category(category_id, force=True)` - Delete category (cascade deletes sections/articles)
193
+
194
+ #### Sections
195
+ - `get_sections()` - List all sections with pagination
196
+ - `get_category_sections(category_id)` - List sections in a category
197
+ - `get_section(section_id)` - Get section by ID
198
+ - `create_section(category_id, name, description, position)` - Create section
199
+ - `update_section(section_id, ...)` - Update section
200
+ - `delete_section(section_id, force=True)` - Delete section (cascade deletes articles)
201
+
202
+ #### Articles
203
+ - `get_articles()` - List all articles with pagination
204
+ - `get_section_articles(section_id)` - List articles in a section
205
+ - `get_category_articles(category_id)` - List articles in a category
206
+ - `get_article(article_id)` - Get article by ID
207
+ - `create_article(section_id, title, body, ...)` - Create article
208
+ - `update_article(article_id, ...)` - Update article
209
+ - `delete_article(article_id)` - Delete article
210
+ - `search_articles(query, ...)` - Full-text search with snippets
211
+
212
+ ```python
213
+ async with ZendeskClient(config) as client:
214
+ hc = client.help_center
215
+
216
+ # Create category -> section -> article hierarchy
217
+ category = await hc.create_category(
218
+ name="Product Documentation",
219
+ description="Help articles for our product"
220
+ )
221
+
222
+ section = await hc.create_section(
223
+ category_id=category.id,
224
+ name="Getting Started"
225
+ )
226
+
227
+ article = await hc.create_article(
228
+ section_id=section.id,
229
+ title="Installation Guide",
230
+ body="<h1>Installation</h1><p>Follow these steps...</p>",
231
+ permission_group_id=252606, # Required
232
+ draft=False, # Publish immediately
233
+ label_names=["installation", "guide"],
234
+ )
235
+
236
+ # Search articles (useful for AI assistants)
237
+ results = await hc.search_articles("password reset")
238
+ for article in results:
239
+ print(f"{article.title}")
240
+ print(f"Snippet: {article.snippet}") # Matching text with <em> tags
241
+
242
+ # Paginate through all articles
243
+ paginator = await hc.get_articles(per_page=50)
244
+ async for article_data in paginator:
245
+ print(article_data["title"])
246
+
247
+ # Update article
248
+ await hc.update_article(
249
+ article.id,
250
+ title="Updated Title",
251
+ promoted=True,
252
+ label_names=["updated", "featured"],
253
+ )
254
+
255
+ # Cascade delete (removes category + all sections + all articles)
256
+ await hc.delete_category(category.id, force=True)
257
+ ```
258
+
259
+ > **Note**: `delete_category()` and `delete_section()` require `force=True` as a safety measure since they cascade delete all child content.
260
+
182
261
  ## Error Handling
183
262
 
184
263
  The SDK provides specific exception classes for different error types:
@@ -234,6 +313,7 @@ See the `examples/` directory for complete usage examples:
234
313
  - `pagination_example.py` - Working with paginated results
235
314
  - `error_handling.py` - Error handling patterns
236
315
  - `enriched_tickets.py` - Loading tickets with related data
316
+ - `help_center.py` - Help Center categories, sections, and articles
237
317
 
238
318
  ## Requirements
239
319
 
@@ -0,0 +1,141 @@
1
+ """Help Center example for Zendesk SDK.
2
+
3
+ This example demonstrates:
4
+ - Help Center hierarchy (Categories -> Sections -> Articles)
5
+ - CRUD operations for categories, sections, and articles
6
+ - Article search with snippets
7
+ - Pagination through Help Center content
8
+ - Cascade deletion with force parameter
9
+ """
10
+
11
+ import asyncio
12
+
13
+ from zendesk_sdk import ZendeskClient, ZendeskConfig
14
+
15
+
16
+ async def main() -> None:
17
+ # Configuration
18
+ config = ZendeskConfig(
19
+ subdomain="your-subdomain",
20
+ email="your-email@example.com",
21
+ token="your-api-token",
22
+ )
23
+
24
+ async with ZendeskClient(config) as client:
25
+ hc = client.help_center
26
+
27
+ # ==================== Reading Content ====================
28
+
29
+ # List categories with pagination
30
+ print("--- Categories ---")
31
+ categories_paginator = await hc.get_categories(per_page=10)
32
+ categories = await categories_paginator.get_page()
33
+ for cat in categories[:5]:
34
+ print(f"Category: {cat['name']} (ID: {cat['id']})")
35
+
36
+ # Get specific category
37
+ if categories:
38
+ category = await hc.get_category(categories[0]["id"])
39
+ print(f"\nCategory details: {category.name}")
40
+ print(f"Description: {category.description}")
41
+
42
+ # List sections (all or by category)
43
+ print("\n--- Sections ---")
44
+ sections_paginator = await hc.get_sections(per_page=10)
45
+ sections = await sections_paginator.get_page()
46
+ for sec in sections[:5]:
47
+ print(f"Section: {sec['name']} (Category: {sec['category_id']})")
48
+
49
+ # List articles in a section
50
+ if sections:
51
+ section_id = sections[0]["id"]
52
+ articles_paginator = await hc.get_section_articles(section_id, per_page=10)
53
+ articles = await articles_paginator.get_page()
54
+ print(f"\nArticles in section {section_id}:")
55
+ for art in articles[:5]:
56
+ print(f" - {art['title']}")
57
+
58
+ # ==================== Search ====================
59
+
60
+ # Search articles (useful for AI assistants)
61
+ print("\n--- Article Search ---")
62
+ search_results = await hc.search_articles("password reset", per_page=5)
63
+ for article in search_results:
64
+ print(f"Found: {article.title}")
65
+ if article.snippet:
66
+ print(f" Snippet: {article.snippet[:100]}...")
67
+
68
+ # ==================== CRUD Operations ====================
69
+
70
+ # Create a category
71
+ print("\n--- Creating Content ---")
72
+ new_category = await hc.create_category(
73
+ name="API Documentation",
74
+ description="Documentation for our REST API",
75
+ )
76
+ print(f"Created category: {new_category.name} (ID: {new_category.id})")
77
+
78
+ # Create a section in the category
79
+ new_section = await hc.create_section(
80
+ category_id=new_category.id,
81
+ name="Getting Started",
82
+ description="Quick start guides",
83
+ )
84
+ print(f"Created section: {new_section.name} (ID: {new_section.id})")
85
+
86
+ # Create an article in the section
87
+ new_article = await hc.create_article(
88
+ section_id=new_section.id,
89
+ title="Authentication Guide",
90
+ body="<h1>Authentication</h1><p>Use API tokens to authenticate...</p>",
91
+ draft=True, # Create as draft first
92
+ permission_group_id=252606, # Required - get from existing articles
93
+ label_names=["api", "authentication", "getting-started"],
94
+ )
95
+ print(f"Created article: {new_article.title} (draft: {new_article.draft})")
96
+
97
+ # Update the article
98
+ updated_article = await hc.update_article(
99
+ new_article.id,
100
+ title="Authentication Guide - Updated",
101
+ draft=False, # Publish the article
102
+ promoted=True, # Feature it
103
+ )
104
+ print(f"Updated article: {updated_article.title} (promoted: {updated_article.promoted})")
105
+
106
+ # Delete individual article
107
+ await hc.delete_article(new_article.id)
108
+ print("Deleted article")
109
+
110
+ # Create another article for cascade delete demo
111
+ demo_article = await hc.create_article(
112
+ section_id=new_section.id,
113
+ title="Demo Article",
114
+ body="<p>This will be deleted with the category</p>",
115
+ draft=True,
116
+ permission_group_id=252606,
117
+ )
118
+ print(f"Created demo article: {demo_article.title}")
119
+
120
+ # Cascade delete - removes category, section, and all articles
121
+ # force=True is required as a safety measure
122
+ await hc.delete_category(new_category.id, force=True)
123
+ print("Deleted category (cascade deleted section and article)")
124
+
125
+ # ==================== Pagination ====================
126
+
127
+ # Iterate through all articles with async for
128
+ print("\n--- Pagination Example ---")
129
+ all_articles_paginator = await hc.get_articles(per_page=10)
130
+ count = 0
131
+ async for article_data in all_articles_paginator:
132
+ count += 1
133
+ if count <= 3:
134
+ print(f"Article {count}: {article_data['title'][:40]}...")
135
+ if count >= 10:
136
+ print(f"... and more (stopped at {count})")
137
+ break
138
+
139
+
140
+ if __name__ == "__main__":
141
+ asyncio.run(main())
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-zendesk-sdk"
3
- version = "0.1.2"
3
+ version = "0.1.3"
4
4
  description = "Modern Python SDK for Zendesk API"
5
5
  authors = [
6
6
  {name = "bormog"}
@@ -5,7 +5,7 @@ This package provides a clean, async-first interface to the Zendesk API
5
5
  with full type safety and comprehensive error handling.
6
6
  """
7
7
 
8
- __version__ = "0.1.2"
8
+ __version__ = "0.1.3"
9
9
 
10
10
  from .client import ZendeskClient
11
11
  from .config import ZendeskConfig
@@ -16,12 +16,19 @@ from .exceptions import (
16
16
  ZendeskPaginationException,
17
17
  ZendeskRateLimitException,
18
18
  )
19
- from .models import EnrichedTicket
19
+ from .help_center_client import HelpCenterClient
20
+ from .models import Article, Category, EnrichedTicket, Section
20
21
 
21
22
  __all__ = [
22
23
  "ZendeskClient",
23
24
  "ZendeskConfig",
25
+ "HelpCenterClient",
24
26
  "EnrichedTicket",
27
+ # Help Center models
28
+ "Category",
29
+ "Section",
30
+ "Article",
31
+ # Exceptions
25
32
  "ZendeskBaseException",
26
33
  "ZendeskHTTPException",
27
34
  "ZendeskAuthException",
@@ -11,6 +11,7 @@ from .models import Comment, EnrichedTicket, Organization, Ticket, User
11
11
  from .pagination import ZendeskPaginator
12
12
 
13
13
  if TYPE_CHECKING:
14
+ from .help_center_client import HelpCenterClient
14
15
  from .pagination import Paginator
15
16
 
16
17
 
@@ -30,6 +31,7 @@ class ZendeskClient:
30
31
  """
31
32
  self.config = config
32
33
  self._http_client: Optional[HTTPClient] = None
34
+ self._help_center_client: Optional["HelpCenterClient"] = None
33
35
 
34
36
  def __repr__(self) -> str:
35
37
  """String representation of the client."""
@@ -42,6 +44,37 @@ class ZendeskClient:
42
44
  self._http_client = HTTPClient(self.config)
43
45
  return self._http_client
44
46
 
47
+ @property
48
+ def help_center(self) -> "HelpCenterClient":
49
+ """Get Help Center client for accessing Help Center API.
50
+
51
+ The Help Center client provides access to categories, sections,
52
+ and articles in your Zendesk Help Center / Guide.
53
+
54
+ Returns:
55
+ HelpCenterClient instance
56
+
57
+ Example:
58
+ async with ZendeskClient(config) as client:
59
+ # Get a category
60
+ category = await client.help_center.get_category(123)
61
+
62
+ # Search articles
63
+ articles = await client.help_center.search_articles("password reset")
64
+
65
+ # Create an article
66
+ article = await client.help_center.create_article(
67
+ section_id=456,
68
+ title="How to Reset Password",
69
+ body="<p>Follow these steps...</p>"
70
+ )
71
+ """
72
+ if self._help_center_client is None:
73
+ from .help_center_client import HelpCenterClient
74
+
75
+ self._help_center_client = HelpCenterClient(self.http_client)
76
+ return self._help_center_client
77
+
45
78
  async def get(
46
79
  self,
47
80
  path: str,