Apache Airflow provider package for integrating with Zendesk API through hooks and connection types
npx @tessl/cli install tessl/pypi-apache-airflow-providers-zendesk@4.10.00
# Apache Airflow Providers Zendesk
1
2
Apache Airflow provider package for integrating with Zendesk customer service platform. This provider enables Airflow DAGs to interact with Zendesk's API through a standardized hook interface, allowing automated customer service workflows and data synchronization.
3
4
## Package Information
5
6
- **Package Name**: apache-airflow-providers-zendesk
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install apache-airflow-providers-zendesk`
10
- **Requirements**: Apache Airflow >= 2.10.0, zenpy >= 2.0.40
11
- **Python Versions**: 3.10, 3.11, 3.12, 3.13
12
13
## Core Imports
14
15
```python
16
from airflow.providers.zendesk.hooks.zendesk import ZendeskHook
17
```
18
19
Version compatibility imports:
20
21
```python
22
from airflow.providers.zendesk.version_compat import BaseHook, BaseOperator
23
```
24
25
Provider info:
26
27
```python
28
from airflow.providers.zendesk.get_provider_info import get_provider_info
29
```
30
31
## Basic Usage
32
33
```python
34
from airflow.providers.zendesk.hooks.zendesk import ZendeskHook
35
from airflow import DAG
36
from airflow.decorators import task
37
from datetime import datetime
38
39
@task
40
def manage_zendesk_tickets():
41
# Initialize hook with connection ID
42
hook = ZendeskHook(zendesk_conn_id='zendesk_default')
43
44
# Search for tickets
45
tickets = list(hook.search_tickets(status='open', type='incident'))
46
47
# Get specific ticket
48
if tickets:
49
ticket = hook.get_ticket(tickets[0].id)
50
print(f"Ticket {ticket.id}: {ticket.subject}")
51
52
return len(tickets)
53
54
# DAG definition
55
with DAG(
56
'zendesk_workflow',
57
start_date=datetime(2023, 1, 1),
58
schedule_interval=None,
59
catchup=False
60
) as dag:
61
manage_zendesk_tickets()
62
```
63
64
## Connection Configuration
65
66
Configure Zendesk connection in Airflow:
67
68
- **Connection Type**: `zendesk`
69
- **Host**: Your Zendesk domain (e.g., `yourcompany.zendesk.com`)
70
- **Login**: Zendesk email address
71
- **Password**: Zendesk password or API token
72
73
## Capabilities
74
75
### Zendesk Hook
76
77
Main hook class for interacting with Zendesk API through the zenpy client library.
78
79
```python { .api }
80
class ZendeskHook(BaseHook):
81
"""
82
Interact with Zendesk. This hook uses the Zendesk conn_id.
83
84
:param zendesk_conn_id: The Airflow connection used for Zendesk credentials.
85
"""
86
87
conn_name_attr: str = "zendesk_conn_id"
88
default_conn_name: str = "zendesk_default"
89
conn_type: str = "zendesk"
90
hook_name: str = "Zendesk"
91
92
def __init__(self, zendesk_conn_id: str = default_conn_name) -> None:
93
"""Initialize ZendeskHook with connection ID."""
94
95
@classmethod
96
def get_ui_field_behaviour(cls) -> dict[str, Any]:
97
"""
98
Return UI field configuration for Airflow connection form.
99
100
Returns:
101
dict: Configuration hiding schema, port, extra fields and relabeling host/login
102
"""
103
104
def get_conn(self) -> Zenpy:
105
"""
106
Get the underlying Zenpy client.
107
108
Returns:
109
zenpy.Zenpy: Configured Zenpy client instance
110
"""
111
112
def get_ticket(self, ticket_id: int) -> Ticket:
113
"""
114
Retrieve ticket by ID.
115
116
Args:
117
ticket_id: The ID of the ticket to retrieve
118
119
Returns:
120
Ticket: Zendesk ticket object
121
"""
122
123
def search_tickets(self, **kwargs) -> SearchResultGenerator:
124
"""
125
Search tickets with optional parameters.
126
127
Args:
128
**kwargs: Search fields for zenpy search method (status, type, priority, etc.)
129
130
Returns:
131
SearchResultGenerator: Generator of matching Ticket objects
132
"""
133
134
def create_tickets(self, tickets: Ticket | list[Ticket], **kwargs) -> TicketAudit | JobStatus:
135
"""
136
Create single ticket or multiple tickets.
137
138
Args:
139
tickets: Single Ticket or list of Ticket objects to create
140
**kwargs: Additional fields for zenpy create method
141
142
Returns:
143
TicketAudit: Information about ticket created (single ticket)
144
JobStatus: Job status object (bulk request)
145
"""
146
147
def update_tickets(self, tickets: Ticket | list[Ticket], **kwargs) -> TicketAudit | JobStatus:
148
"""
149
Update single ticket or multiple tickets.
150
151
Args:
152
tickets: Updated Ticket or list of Ticket objects
153
**kwargs: Additional fields for zenpy update method
154
155
Returns:
156
TicketAudit: Information about ticket updated (single ticket)
157
JobStatus: Job status object (bulk request)
158
"""
159
160
def delete_tickets(self, tickets: Ticket | list[Ticket], **kwargs) -> None:
161
"""
162
Delete single ticket or multiple tickets.
163
164
Args:
165
tickets: Ticket or list of Ticket objects to delete
166
**kwargs: Additional fields for zenpy delete method
167
168
Returns:
169
None: Returns nothing on success, raises APIException on failure
170
"""
171
172
def get(self, *args, **kwargs):
173
"""
174
Make custom GET request using zenpy client's users API.
175
176
Note: This is an alias to the underlying zenpy client's users._get method.
177
178
Args:
179
*args: Positional arguments passed to zenpy client
180
**kwargs: Keyword arguments passed to zenpy client
181
182
Returns:
183
API response from zenpy client
184
"""
185
```
186
187
### Version Compatibility Utilities
188
189
Compatibility functions and constants for different Airflow versions.
190
191
```python { .api }
192
def get_base_airflow_version_tuple() -> tuple[int, int, int]:
193
"""
194
Get Airflow version as tuple.
195
196
Returns:
197
tuple[int, int, int]: Major, minor, micro version numbers
198
"""
199
200
# Version check constants
201
AIRFLOW_V_3_0_PLUS: bool # Whether running Airflow 3.0+
202
AIRFLOW_V_3_1_PLUS: bool # Whether running Airflow 3.1+
203
204
# Version-dependent imports
205
BaseHook: type # From airflow.sdk or airflow.hooks.base
206
BaseOperator: type # From airflow.sdk or airflow.models
207
```
208
209
**Import from version_compat module:**
210
211
```python
212
from airflow.providers.zendesk.version_compat import (
213
get_base_airflow_version_tuple,
214
AIRFLOW_V_3_0_PLUS,
215
AIRFLOW_V_3_1_PLUS,
216
BaseHook,
217
BaseOperator
218
)
219
```
220
221
### Provider Information
222
223
Function to retrieve provider metadata for Airflow discovery.
224
225
```python { .api }
226
def get_provider_info() -> dict:
227
"""
228
Get provider package information.
229
230
Returns:
231
dict: Provider metadata including package name, integrations, hooks, and connection types
232
"""
233
```
234
235
## Types
236
237
Types from the zenpy library that are commonly used with this provider:
238
239
```python { .api }
240
# From zenpy library
241
class Zenpy:
242
"""Main zenpy client for Zendesk API."""
243
244
class Ticket:
245
"""Zendesk ticket object containing ticket data and methods."""
246
247
id: int
248
subject: str
249
description: str
250
status: str
251
priority: str
252
# ... additional ticket fields
253
254
class TicketAudit:
255
"""Information about ticket creation/update operations."""
256
257
class JobStatus:
258
"""Status information for bulk operations."""
259
260
class SearchResultGenerator:
261
"""Generator yielding search results from Zendesk API."""
262
263
# Union types for method parameters
264
TicketInput = Ticket | list[Ticket]
265
TicketResult = TicketAudit | JobStatus
266
```
267
268
## Usage Examples
269
270
### Create and Update Tickets
271
272
```python
273
from airflow.providers.zendesk.hooks.zendesk import ZendeskHook
274
from zenpy.lib.api_objects import Ticket
275
276
hook = ZendeskHook()
277
278
# Create a new ticket
279
new_ticket = Ticket(
280
subject="Integration Test Ticket",
281
description="This is a test ticket created via Airflow",
282
priority="normal"
283
)
284
285
audit = hook.create_tickets(new_ticket)
286
print(f"Created ticket ID: {audit.ticket.id}")
287
288
# Update the ticket
289
new_ticket.status = "solved"
290
update_audit = hook.update_tickets(new_ticket)
291
print(f"Updated ticket status: {update_audit.ticket.status}")
292
```
293
294
### Bulk Operations
295
296
```python
297
# Create multiple tickets
298
tickets = [
299
Ticket(subject=f"Batch Ticket {i}", description=f"Description {i}")
300
for i in range(1, 4)
301
]
302
303
job_status = hook.create_tickets(tickets)
304
print(f"Bulk create job ID: {job_status.id}")
305
306
# Search and filter tickets
307
open_tickets = list(hook.search_tickets(status="open", type="incident"))
308
print(f"Found {len(open_tickets)} open incident tickets")
309
```
310
311
### Custom API Access
312
313
```python
314
# Access underlying zenpy client for advanced operations
315
zenpy_client = hook.get_conn()
316
317
# Use zenpy client directly
318
users = zenpy_client.users.me()
319
print(f"Current user: {users.name}")
320
321
# Note: The get method is an alias to zenpy client's users._get method
322
# For other API endpoints, use the zenpy client directly
323
response = zenpy_client.organizations()
324
organizations = [org.to_dict() for org in response]
325
```
326
327
## Error Handling
328
329
The provider uses zenpy's exception handling. Common exceptions include:
330
331
- **APIException**: Raised when API operations fail
332
- **Connection errors**: Raised when unable to connect to Zendesk
333
- **Authentication errors**: Raised when credentials are invalid
334
335
```python
336
from zenpy.lib.exception import APIException
337
338
try:
339
ticket = hook.get_ticket(999999) # Non-existent ticket
340
except APIException as e:
341
print(f"API Error: {e}")
342
```