0
# Dagster Twilio
1
2
A Dagster integration for Twilio that enables users to connect to Twilio services within Dagster data pipelines. This package provides both modern Pydantic-based resources and legacy resource functions for integrating Twilio REST API functionality into Dagster workflows.
3
4
## Package Information
5
6
- **Package Name**: dagster-twilio
7
- **Language**: Python
8
- **Installation**: `pip install dagster-twilio`
9
10
## Core Imports
11
12
```python
13
from dagster_twilio import TwilioResource, twilio_resource
14
```
15
16
For version information:
17
18
```python
19
from dagster_twilio import __version__
20
```
21
22
## Basic Usage
23
24
### Modern Resource Approach (Recommended)
25
26
```python
27
from dagster import asset
28
from dagster_twilio import TwilioResource
29
30
@asset
31
def send_notification(twilio_resource: TwilioResource):
32
# Create Twilio client
33
client = twilio_resource.create_client()
34
35
# Send SMS message
36
message = client.messages.create(
37
body="Pipeline completed successfully!",
38
from_="+1234567890",
39
to="+0987654321"
40
)
41
42
return message.sid
43
44
# Configure resource
45
twilio_resource = TwilioResource(
46
account_sid="your_account_sid",
47
auth_token="your_auth_token"
48
)
49
```
50
51
### Legacy Resource Approach
52
53
```python
54
from dagster import op, job
55
from dagster_twilio import twilio_resource
56
57
@op(required_resource_keys={"twilio_resource"})
58
def send_sms_op(context):
59
client = context.resources.twilio_resource
60
61
message = client.messages.create(
62
body="Job completed!",
63
from_="+1234567890",
64
to="+0987654321"
65
)
66
67
return message.sid
68
69
@job(resource_defs={"twilio_resource": twilio_resource})
70
def notification_job():
71
send_sms_op()
72
```
73
74
## Capabilities
75
76
### TwilioResource
77
78
Modern Pydantic-based resource class for Twilio integration that provides secure configuration management and creates Twilio REST API clients.
79
80
```python { .api }
81
class TwilioResource(ConfigurableResource):
82
"""This resource is for connecting to Twilio."""
83
84
account_sid: str = Field(
85
description="Twilio Account SID, created with your Twilio account. This can be found on your Twilio dashboard, see https://www.twilio.com/blog/twilio-access-tokens-python"
86
)
87
auth_token: str = Field(
88
description="Twilio Authentication Token, created with your Twilio account. This can be found on your Twilio dashboard, see https://www.twilio.com/blog/twilio-access-tokens-python"
89
)
90
91
def create_client(self) -> Client:
92
"""Create and return a Twilio REST API client."""
93
94
@classmethod
95
def _is_dagster_maintained(cls) -> bool:
96
"""Indicates this is a Dagster-maintained resource."""
97
```
98
99
**Configuration Fields:**
100
101
- `account_sid` (str): Twilio Account SID from your Twilio dashboard. See [Twilio Access Tokens documentation](https://www.twilio.com/blog/twilio-access-tokens-python) for details.
102
- `auth_token` (str): Twilio Authentication Token from your Twilio dashboard. See [Twilio Access Tokens documentation](https://www.twilio.com/blog/twilio-access-tokens-python) for details.
103
104
**Methods:**
105
106
- `create_client()`: Creates and returns a `twilio.rest.Client` instance configured with the provided credentials
107
- `configure_at_launch()`: Inherited method that allows runtime configuration of the resource
108
109
### twilio_resource
110
111
Legacy resource function that provides Twilio integration using the traditional Dagster resource pattern.
112
113
```python { .api }
114
@dagster_maintained_resource
115
@resource(
116
config_schema=TwilioResource.to_config_schema(),
117
description="This resource is for connecting to Twilio"
118
)
119
def twilio_resource(context: InitResourceContext) -> Client:
120
"""
121
Legacy resource function for Twilio integration.
122
123
Parameters:
124
- context: InitResourceContext with Twilio configuration
125
126
Returns:
127
twilio.rest.Client: Configured Twilio REST API client
128
"""
129
```
130
131
**Configuration Schema:**
132
Uses the same configuration schema as `TwilioResource`:
133
- `account_sid` (str): Twilio Account SID
134
- `auth_token` (str): Twilio Authentication Token
135
136
### Twilio Client Operations
137
138
Both resource approaches return a `twilio.rest.Client` instance that provides access to all Twilio REST API functionality, including:
139
140
- **SMS Messages**: Send and manage SMS messages via `client.messages.create()`
141
- **Voice Calls**: Make voice calls via `client.calls.create()`
142
- **WhatsApp**: Send WhatsApp messages
143
- **Email**: Send emails via SendGrid integration
144
- **Verify**: Phone number verification services
145
- **Lookup**: Phone number information lookup
146
147
Common Twilio client operations:
148
149
```python
150
# Send SMS
151
message = client.messages.create(
152
body="Your message here",
153
from_="+1234567890", # Your Twilio phone number
154
to="+0987654321" # Recipient phone number
155
)
156
157
# Make voice call
158
call = client.calls.create(
159
url="http://demo.twilio.com/docs/voice.xml", # TwiML URL
160
to="+0987654321",
161
from_="+1234567890"
162
)
163
164
# Lookup phone number information
165
phone_number = client.lookups.phone_numbers("+15558675310").fetch()
166
```
167
168
## Types
169
170
```python { .api }
171
# From dagster
172
from dagster import ConfigurableResource, InitResourceContext
173
174
# From pydantic
175
from pydantic import Field
176
177
# From twilio
178
from twilio.rest import Client
179
from twilio.base.exceptions import TwilioRestException
180
181
class TwilioResource(ConfigurableResource):
182
account_sid: str = Field(description="...")
183
auth_token: str = Field(description="...")
184
185
def create_client(self) -> Client: ...
186
187
@classmethod
188
def _is_dagster_maintained(cls) -> bool: ...
189
190
# Package version
191
__version__: str # Currently "0.27.9"
192
```
193
194
## Error Handling
195
196
When working with Twilio operations, handle `TwilioRestException` for API-related errors:
197
198
```python
199
from twilio.base.exceptions import TwilioRestException
200
201
try:
202
message = client.messages.create(
203
body="Test message",
204
from_="+15005550006", # Valid test number
205
to="+15005550001" # Invalid test number
206
)
207
except TwilioRestException as e:
208
context.log.error(f"Twilio API error: {e}")
209
raise
210
```
211
212
## Configuration Best Practices
213
214
### Environment Variables
215
216
Store Twilio credentials securely using environment variables:
217
218
```python
219
import os
220
from dagster_twilio import TwilioResource
221
222
twilio_resource = TwilioResource(
223
account_sid=os.getenv("TWILIO_ACCOUNT_SID"),
224
auth_token=os.getenv("TWILIO_AUTH_TOKEN")
225
)
226
```
227
228
### Dagster Configuration
229
230
Configure via Dagster's configuration system:
231
232
```yaml
233
# dagster.yaml
234
resources:
235
twilio_resource:
236
config:
237
account_sid:
238
env: TWILIO_ACCOUNT_SID
239
auth_token:
240
env: TWILIO_AUTH_TOKEN
241
```
242
243
### Test Credentials
244
245
For testing, use [Twilio's test credentials](https://www.twilio.com/docs/iam/test-credentials):
246
- Test Account SID: Starts with `AC` followed by test identifier
247
- Test Auth Token: Test authentication token
248
- Test phone numbers: `+15005550006` (valid), `+15005550001` (invalid)