definite-sdk 0.1.4__tar.gz → 0.1.9__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.
- definite_sdk-0.1.9/PKG-INFO +314 -0
- definite_sdk-0.1.9/README.md +292 -0
- definite_sdk-0.1.9/definite_sdk/__init__.py +22 -0
- definite_sdk-0.1.9/definite_sdk/client.py +92 -0
- definite_sdk-0.1.9/definite_sdk/dlt.py +237 -0
- definite_sdk-0.1.9/definite_sdk/integration.py +99 -0
- definite_sdk-0.1.9/definite_sdk/message.py +199 -0
- definite_sdk-0.1.9/definite_sdk/py.typed +0 -0
- {definite_sdk-0.1.4 → definite_sdk-0.1.9}/definite_sdk/secret.py +3 -3
- definite_sdk-0.1.9/definite_sdk/sql.py +126 -0
- {definite_sdk-0.1.4 → definite_sdk-0.1.9}/definite_sdk/store.py +18 -2
- {definite_sdk-0.1.4 → definite_sdk-0.1.9}/pyproject.toml +6 -1
- definite_sdk-0.1.4/PKG-INFO +0 -21
- definite_sdk-0.1.4/README.md +0 -3
- definite_sdk-0.1.4/definite_sdk/client.py +0 -41
- definite_sdk-0.1.4/definite_sdk/integration.py +0 -60
- {definite_sdk-0.1.4 → definite_sdk-0.1.9}/LICENSE +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: definite-sdk
|
|
3
|
+
Version: 0.1.9
|
|
4
|
+
Summary: Definite SDK for Python
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Definite
|
|
7
|
+
Author-email: hello@definite.app
|
|
8
|
+
Requires-Python: >=3.9,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Provides-Extra: dlt
|
|
17
|
+
Requires-Dist: dlt (>=1.0,<2.0) ; extra == "dlt"
|
|
18
|
+
Requires-Dist: duckdb (>=1.0,<2.0) ; extra == "dlt"
|
|
19
|
+
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Definite SDK
|
|
23
|
+
|
|
24
|
+
A Python client for interacting with the Definite API, providing a convenient interface for key-value store operations, SQL query execution, secrets management, messaging capabilities, and DLT (Data Load Tool) integration with state persistence.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
**pip:**
|
|
29
|
+
```bash
|
|
30
|
+
pip install definite-sdk
|
|
31
|
+
|
|
32
|
+
# For dlt support
|
|
33
|
+
pip install "definite-sdk[dlt]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**poetry:**
|
|
37
|
+
```bash
|
|
38
|
+
poetry add definite-sdk
|
|
39
|
+
|
|
40
|
+
# For dlt support
|
|
41
|
+
poetry add "definite-sdk[dlt]"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from definite_sdk import DefiniteClient
|
|
48
|
+
|
|
49
|
+
# Initialize the client
|
|
50
|
+
client = DefiniteClient("YOUR_API_KEY")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Features
|
|
54
|
+
|
|
55
|
+
- **Key-Value Store**: Persistent storage with version control and transactional commits
|
|
56
|
+
- **SQL Query Execution**: Execute SQL queries against your connected database integrations
|
|
57
|
+
- **Cube Query Execution**: Execute Cube queries for advanced analytics and data modeling
|
|
58
|
+
- **Secret Management**: Secure storage and retrieval of application secrets
|
|
59
|
+
- **Integration Store**: Read-only access to integration configurations
|
|
60
|
+
- **Messaging**: Send messages through various channels (Slack, and more coming soon)
|
|
61
|
+
- **dlt Integration**: Run dlt pipelines with automatic state persistence to Definite
|
|
62
|
+
- **DuckDB Support**: Automatic discovery and connection to team's DuckDB integrations
|
|
63
|
+
|
|
64
|
+
## Basic Usage
|
|
65
|
+
|
|
66
|
+
### 🗄️ Key-Value Store
|
|
67
|
+
|
|
68
|
+
Store and retrieve key-value pairs that can be accessed by custom Python scripts hosted on Definite.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
# Initialize or retrieve an existing key-value store
|
|
72
|
+
store = client.get_kv_store('test_store')
|
|
73
|
+
# Or use the alias method
|
|
74
|
+
store = client.kv_store('test_store')
|
|
75
|
+
|
|
76
|
+
# Add or update key-value pairs
|
|
77
|
+
store['replication_key'] = 'created_at'
|
|
78
|
+
store['replication_state'] = '2024-05-20'
|
|
79
|
+
store["key1"] = "value1"
|
|
80
|
+
store["key2"] = {"nested": "data"}
|
|
81
|
+
|
|
82
|
+
# Commit changes
|
|
83
|
+
store.commit()
|
|
84
|
+
|
|
85
|
+
# Retrieve values
|
|
86
|
+
print(store['replication_key']) # 'created_at'
|
|
87
|
+
value = store["key1"]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 🗃️ SQL Query Execution
|
|
91
|
+
|
|
92
|
+
Execute SQL queries against your connected database integrations.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
# Initialize the SQL client
|
|
96
|
+
sql_client = client.get_sql_client()
|
|
97
|
+
|
|
98
|
+
# Execute a SQL query
|
|
99
|
+
result = sql_client.execute("SELECT * FROM users LIMIT 10")
|
|
100
|
+
print(result)
|
|
101
|
+
|
|
102
|
+
# Execute a SQL query with a specific integration
|
|
103
|
+
result = sql_client.execute(
|
|
104
|
+
"SELECT COUNT(*) FROM orders WHERE status = 'completed'",
|
|
105
|
+
integration_id="my_database_integration"
|
|
106
|
+
)
|
|
107
|
+
print(result)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 📊 Cube Query Execution
|
|
111
|
+
|
|
112
|
+
Execute Cube queries for advanced analytics and data modeling.
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# Prepare a Cube query
|
|
116
|
+
cube_query = {
|
|
117
|
+
"dimensions": [],
|
|
118
|
+
"measures": ["sales.total_amount"],
|
|
119
|
+
"timeDimensions": [{
|
|
120
|
+
"dimension": "sales.date",
|
|
121
|
+
"granularity": "month"
|
|
122
|
+
}],
|
|
123
|
+
"limit": 1000
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Execute the Cube query
|
|
127
|
+
result = sql_client.execute_cube_query(
|
|
128
|
+
cube_query,
|
|
129
|
+
integration_id="my_cube_integration"
|
|
130
|
+
)
|
|
131
|
+
print(result)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 🔒 Secret Store
|
|
135
|
+
|
|
136
|
+
Securely store and retrieve secrets for your integrations.
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Initialize the secret store
|
|
140
|
+
secret_store = client.get_secret_store()
|
|
141
|
+
# Or use the alias method
|
|
142
|
+
secret_store = client.secret_store()
|
|
143
|
+
|
|
144
|
+
# Set a secret
|
|
145
|
+
secret_store.set_secret("database_password", "my_secure_password")
|
|
146
|
+
|
|
147
|
+
# Get a secret
|
|
148
|
+
password = secret_store.get_secret("database_password")
|
|
149
|
+
|
|
150
|
+
# List all secrets
|
|
151
|
+
secrets = list(secret_store.list_secrets())
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 🔗 Integration Management
|
|
155
|
+
|
|
156
|
+
Manage your data integrations and connections.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
# Initialize the integration store
|
|
160
|
+
integration_store = client.get_integration_store()
|
|
161
|
+
# Or use the alias method
|
|
162
|
+
integration_store = client.integration_store()
|
|
163
|
+
|
|
164
|
+
# List all integrations
|
|
165
|
+
integrations = list(integration_store.list_integrations())
|
|
166
|
+
|
|
167
|
+
# Get a specific integration
|
|
168
|
+
integration = integration_store.get_integration("my_integration")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 💬 Messaging
|
|
172
|
+
|
|
173
|
+
Send messages through various channels using the messaging client.
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
# Initialize the message client
|
|
177
|
+
message_client = client.get_message_client()
|
|
178
|
+
# Or use the alias method
|
|
179
|
+
message_client = client.message_client()
|
|
180
|
+
|
|
181
|
+
# Send a Slack message using the unified interface
|
|
182
|
+
result = message_client.send_message(
|
|
183
|
+
channel="slack",
|
|
184
|
+
integration_id="your_slack_integration_id",
|
|
185
|
+
to="C0920MVPWFN", # Slack channel ID
|
|
186
|
+
content="Hello from Definite SDK! 👋"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Send a Slack message with blocks and threading
|
|
190
|
+
result = message_client.send_message(
|
|
191
|
+
channel="slack",
|
|
192
|
+
integration_id="your_slack_integration_id",
|
|
193
|
+
to="C0920MVPWFN",
|
|
194
|
+
content="Fallback text",
|
|
195
|
+
blocks=[{
|
|
196
|
+
"type": "section",
|
|
197
|
+
"text": {"type": "mrkdwn", "text": "*Important Update*"}
|
|
198
|
+
}],
|
|
199
|
+
thread_ts="1234567890.123456" # Reply in thread
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Or use the convenience method for Slack
|
|
203
|
+
result = message_client.send_slack_message(
|
|
204
|
+
integration_id="your_slack_integration_id",
|
|
205
|
+
channel_id="C0920MVPWFN",
|
|
206
|
+
text="Quick message using the convenience method!",
|
|
207
|
+
blocks=[{
|
|
208
|
+
"type": "section",
|
|
209
|
+
"text": {"type": "mrkdwn", "text": "Message with *rich* _formatting_"}
|
|
210
|
+
}]
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### dlt Integration
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
from definite_sdk.dlt import DefiniteDLTPipeline
|
|
218
|
+
import dlt
|
|
219
|
+
|
|
220
|
+
# Create an incremental resource
|
|
221
|
+
@dlt.resource(primary_key="id", write_disposition="merge")
|
|
222
|
+
def orders(cursor=dlt.sources.incremental("created_at")):
|
|
223
|
+
# Your data loading logic here
|
|
224
|
+
pass
|
|
225
|
+
|
|
226
|
+
# Create and run pipeline
|
|
227
|
+
pipeline = DefiniteDLTPipeline("orders_sync")
|
|
228
|
+
pipeline.run(orders())
|
|
229
|
+
|
|
230
|
+
# State is automatically persisted to Definite
|
|
231
|
+
last_cursor = pipeline.get_state("orders")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### DuckDB Integration Discovery
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from definite_sdk.dlt import get_duckdb_connection
|
|
238
|
+
|
|
239
|
+
# Automatically discovers DuckDB integration using DEFINITE_API_KEY env var
|
|
240
|
+
result = get_duckdb_connection()
|
|
241
|
+
if result:
|
|
242
|
+
integration_id, connection = result
|
|
243
|
+
# Use the DuckDB connection
|
|
244
|
+
connection.execute("SELECT * FROM my_table")
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Note**: DuckDB integration discovery is currently limited as the API only exposes source integrations, not destination integrations. This functionality is provided for future compatibility.
|
|
248
|
+
|
|
249
|
+
### State Management
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
# Set custom state
|
|
253
|
+
pipeline.set_state("custom_key", "custom_value")
|
|
254
|
+
|
|
255
|
+
# Get all state
|
|
256
|
+
all_state = pipeline.get_state()
|
|
257
|
+
|
|
258
|
+
# Resume from previous state
|
|
259
|
+
pipeline.resume_from_state()
|
|
260
|
+
|
|
261
|
+
# Reset state
|
|
262
|
+
pipeline.reset_state()
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Authentication
|
|
266
|
+
|
|
267
|
+
To use the Definite SDK, you'll need an API key. You can find and copy your API key from the bottom left user menu in your Definite workspace.
|
|
268
|
+
|
|
269
|
+
For SQL queries, you'll also need your integration ID, which can be found in your integration's page URL.
|
|
270
|
+
|
|
271
|
+
## Environment Variables
|
|
272
|
+
|
|
273
|
+
- `DEFINITE_API_KEY`: Your Definite API key (auto-injected in Definite runtime)
|
|
274
|
+
- `DEF_API_KEY`: Alternative environment variable for API key
|
|
275
|
+
|
|
276
|
+
## Error Handling
|
|
277
|
+
|
|
278
|
+
The SDK uses standard HTTP status codes and raises `requests.HTTPError` for API errors:
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
import requests
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
result = sql_client.execute("SELECT * FROM invalid_table")
|
|
285
|
+
except requests.HTTPError as e:
|
|
286
|
+
print(f"API Error: {e}")
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Testing
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Run all tests
|
|
293
|
+
DEF_API_KEY=your_api_key poetry run pytest
|
|
294
|
+
|
|
295
|
+
# Run specific test file
|
|
296
|
+
DEF_API_KEY=your_api_key poetry run pytest tests/test_dlt.py
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Contributing
|
|
300
|
+
|
|
301
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
302
|
+
|
|
303
|
+
## License
|
|
304
|
+
|
|
305
|
+
This project is licensed under the MIT License.
|
|
306
|
+
|
|
307
|
+
## Documentation
|
|
308
|
+
|
|
309
|
+
For more detailed documentation, visit: https://docs.definite.app/
|
|
310
|
+
|
|
311
|
+
## Support
|
|
312
|
+
|
|
313
|
+
If you encounter any issues or have questions, please reach out to hello@definite.app
|
|
314
|
+
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Definite SDK
|
|
2
|
+
|
|
3
|
+
A Python client for interacting with the Definite API, providing a convenient interface for key-value store operations, SQL query execution, secrets management, messaging capabilities, and DLT (Data Load Tool) integration with state persistence.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
**pip:**
|
|
8
|
+
```bash
|
|
9
|
+
pip install definite-sdk
|
|
10
|
+
|
|
11
|
+
# For dlt support
|
|
12
|
+
pip install "definite-sdk[dlt]"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**poetry:**
|
|
16
|
+
```bash
|
|
17
|
+
poetry add definite-sdk
|
|
18
|
+
|
|
19
|
+
# For dlt support
|
|
20
|
+
poetry add "definite-sdk[dlt]"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from definite_sdk import DefiniteClient
|
|
27
|
+
|
|
28
|
+
# Initialize the client
|
|
29
|
+
client = DefiniteClient("YOUR_API_KEY")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- **Key-Value Store**: Persistent storage with version control and transactional commits
|
|
35
|
+
- **SQL Query Execution**: Execute SQL queries against your connected database integrations
|
|
36
|
+
- **Cube Query Execution**: Execute Cube queries for advanced analytics and data modeling
|
|
37
|
+
- **Secret Management**: Secure storage and retrieval of application secrets
|
|
38
|
+
- **Integration Store**: Read-only access to integration configurations
|
|
39
|
+
- **Messaging**: Send messages through various channels (Slack, and more coming soon)
|
|
40
|
+
- **dlt Integration**: Run dlt pipelines with automatic state persistence to Definite
|
|
41
|
+
- **DuckDB Support**: Automatic discovery and connection to team's DuckDB integrations
|
|
42
|
+
|
|
43
|
+
## Basic Usage
|
|
44
|
+
|
|
45
|
+
### 🗄️ Key-Value Store
|
|
46
|
+
|
|
47
|
+
Store and retrieve key-value pairs that can be accessed by custom Python scripts hosted on Definite.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
# Initialize or retrieve an existing key-value store
|
|
51
|
+
store = client.get_kv_store('test_store')
|
|
52
|
+
# Or use the alias method
|
|
53
|
+
store = client.kv_store('test_store')
|
|
54
|
+
|
|
55
|
+
# Add or update key-value pairs
|
|
56
|
+
store['replication_key'] = 'created_at'
|
|
57
|
+
store['replication_state'] = '2024-05-20'
|
|
58
|
+
store["key1"] = "value1"
|
|
59
|
+
store["key2"] = {"nested": "data"}
|
|
60
|
+
|
|
61
|
+
# Commit changes
|
|
62
|
+
store.commit()
|
|
63
|
+
|
|
64
|
+
# Retrieve values
|
|
65
|
+
print(store['replication_key']) # 'created_at'
|
|
66
|
+
value = store["key1"]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 🗃️ SQL Query Execution
|
|
70
|
+
|
|
71
|
+
Execute SQL queries against your connected database integrations.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
# Initialize the SQL client
|
|
75
|
+
sql_client = client.get_sql_client()
|
|
76
|
+
|
|
77
|
+
# Execute a SQL query
|
|
78
|
+
result = sql_client.execute("SELECT * FROM users LIMIT 10")
|
|
79
|
+
print(result)
|
|
80
|
+
|
|
81
|
+
# Execute a SQL query with a specific integration
|
|
82
|
+
result = sql_client.execute(
|
|
83
|
+
"SELECT COUNT(*) FROM orders WHERE status = 'completed'",
|
|
84
|
+
integration_id="my_database_integration"
|
|
85
|
+
)
|
|
86
|
+
print(result)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 📊 Cube Query Execution
|
|
90
|
+
|
|
91
|
+
Execute Cube queries for advanced analytics and data modeling.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
# Prepare a Cube query
|
|
95
|
+
cube_query = {
|
|
96
|
+
"dimensions": [],
|
|
97
|
+
"measures": ["sales.total_amount"],
|
|
98
|
+
"timeDimensions": [{
|
|
99
|
+
"dimension": "sales.date",
|
|
100
|
+
"granularity": "month"
|
|
101
|
+
}],
|
|
102
|
+
"limit": 1000
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Execute the Cube query
|
|
106
|
+
result = sql_client.execute_cube_query(
|
|
107
|
+
cube_query,
|
|
108
|
+
integration_id="my_cube_integration"
|
|
109
|
+
)
|
|
110
|
+
print(result)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 🔒 Secret Store
|
|
114
|
+
|
|
115
|
+
Securely store and retrieve secrets for your integrations.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Initialize the secret store
|
|
119
|
+
secret_store = client.get_secret_store()
|
|
120
|
+
# Or use the alias method
|
|
121
|
+
secret_store = client.secret_store()
|
|
122
|
+
|
|
123
|
+
# Set a secret
|
|
124
|
+
secret_store.set_secret("database_password", "my_secure_password")
|
|
125
|
+
|
|
126
|
+
# Get a secret
|
|
127
|
+
password = secret_store.get_secret("database_password")
|
|
128
|
+
|
|
129
|
+
# List all secrets
|
|
130
|
+
secrets = list(secret_store.list_secrets())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 🔗 Integration Management
|
|
134
|
+
|
|
135
|
+
Manage your data integrations and connections.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
# Initialize the integration store
|
|
139
|
+
integration_store = client.get_integration_store()
|
|
140
|
+
# Or use the alias method
|
|
141
|
+
integration_store = client.integration_store()
|
|
142
|
+
|
|
143
|
+
# List all integrations
|
|
144
|
+
integrations = list(integration_store.list_integrations())
|
|
145
|
+
|
|
146
|
+
# Get a specific integration
|
|
147
|
+
integration = integration_store.get_integration("my_integration")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 💬 Messaging
|
|
151
|
+
|
|
152
|
+
Send messages through various channels using the messaging client.
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Initialize the message client
|
|
156
|
+
message_client = client.get_message_client()
|
|
157
|
+
# Or use the alias method
|
|
158
|
+
message_client = client.message_client()
|
|
159
|
+
|
|
160
|
+
# Send a Slack message using the unified interface
|
|
161
|
+
result = message_client.send_message(
|
|
162
|
+
channel="slack",
|
|
163
|
+
integration_id="your_slack_integration_id",
|
|
164
|
+
to="C0920MVPWFN", # Slack channel ID
|
|
165
|
+
content="Hello from Definite SDK! 👋"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Send a Slack message with blocks and threading
|
|
169
|
+
result = message_client.send_message(
|
|
170
|
+
channel="slack",
|
|
171
|
+
integration_id="your_slack_integration_id",
|
|
172
|
+
to="C0920MVPWFN",
|
|
173
|
+
content="Fallback text",
|
|
174
|
+
blocks=[{
|
|
175
|
+
"type": "section",
|
|
176
|
+
"text": {"type": "mrkdwn", "text": "*Important Update*"}
|
|
177
|
+
}],
|
|
178
|
+
thread_ts="1234567890.123456" # Reply in thread
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Or use the convenience method for Slack
|
|
182
|
+
result = message_client.send_slack_message(
|
|
183
|
+
integration_id="your_slack_integration_id",
|
|
184
|
+
channel_id="C0920MVPWFN",
|
|
185
|
+
text="Quick message using the convenience method!",
|
|
186
|
+
blocks=[{
|
|
187
|
+
"type": "section",
|
|
188
|
+
"text": {"type": "mrkdwn", "text": "Message with *rich* _formatting_"}
|
|
189
|
+
}]
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### dlt Integration
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from definite_sdk.dlt import DefiniteDLTPipeline
|
|
197
|
+
import dlt
|
|
198
|
+
|
|
199
|
+
# Create an incremental resource
|
|
200
|
+
@dlt.resource(primary_key="id", write_disposition="merge")
|
|
201
|
+
def orders(cursor=dlt.sources.incremental("created_at")):
|
|
202
|
+
# Your data loading logic here
|
|
203
|
+
pass
|
|
204
|
+
|
|
205
|
+
# Create and run pipeline
|
|
206
|
+
pipeline = DefiniteDLTPipeline("orders_sync")
|
|
207
|
+
pipeline.run(orders())
|
|
208
|
+
|
|
209
|
+
# State is automatically persisted to Definite
|
|
210
|
+
last_cursor = pipeline.get_state("orders")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### DuckDB Integration Discovery
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from definite_sdk.dlt import get_duckdb_connection
|
|
217
|
+
|
|
218
|
+
# Automatically discovers DuckDB integration using DEFINITE_API_KEY env var
|
|
219
|
+
result = get_duckdb_connection()
|
|
220
|
+
if result:
|
|
221
|
+
integration_id, connection = result
|
|
222
|
+
# Use the DuckDB connection
|
|
223
|
+
connection.execute("SELECT * FROM my_table")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Note**: DuckDB integration discovery is currently limited as the API only exposes source integrations, not destination integrations. This functionality is provided for future compatibility.
|
|
227
|
+
|
|
228
|
+
### State Management
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
# Set custom state
|
|
232
|
+
pipeline.set_state("custom_key", "custom_value")
|
|
233
|
+
|
|
234
|
+
# Get all state
|
|
235
|
+
all_state = pipeline.get_state()
|
|
236
|
+
|
|
237
|
+
# Resume from previous state
|
|
238
|
+
pipeline.resume_from_state()
|
|
239
|
+
|
|
240
|
+
# Reset state
|
|
241
|
+
pipeline.reset_state()
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Authentication
|
|
245
|
+
|
|
246
|
+
To use the Definite SDK, you'll need an API key. You can find and copy your API key from the bottom left user menu in your Definite workspace.
|
|
247
|
+
|
|
248
|
+
For SQL queries, you'll also need your integration ID, which can be found in your integration's page URL.
|
|
249
|
+
|
|
250
|
+
## Environment Variables
|
|
251
|
+
|
|
252
|
+
- `DEFINITE_API_KEY`: Your Definite API key (auto-injected in Definite runtime)
|
|
253
|
+
- `DEF_API_KEY`: Alternative environment variable for API key
|
|
254
|
+
|
|
255
|
+
## Error Handling
|
|
256
|
+
|
|
257
|
+
The SDK uses standard HTTP status codes and raises `requests.HTTPError` for API errors:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
import requests
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
result = sql_client.execute("SELECT * FROM invalid_table")
|
|
264
|
+
except requests.HTTPError as e:
|
|
265
|
+
print(f"API Error: {e}")
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Testing
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# Run all tests
|
|
272
|
+
DEF_API_KEY=your_api_key poetry run pytest
|
|
273
|
+
|
|
274
|
+
# Run specific test file
|
|
275
|
+
DEF_API_KEY=your_api_key poetry run pytest tests/test_dlt.py
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Contributing
|
|
279
|
+
|
|
280
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
This project is licensed under the MIT License.
|
|
285
|
+
|
|
286
|
+
## Documentation
|
|
287
|
+
|
|
288
|
+
For more detailed documentation, visit: https://docs.definite.app/
|
|
289
|
+
|
|
290
|
+
## Support
|
|
291
|
+
|
|
292
|
+
If you encounter any issues or have questions, please reach out to hello@definite.app
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Definite SDK for Python
|
|
3
|
+
|
|
4
|
+
A Python library for interacting with the Definite API and tools.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from definite_sdk.client import DefiniteClient
|
|
8
|
+
from definite_sdk.integration import DefiniteIntegrationStore
|
|
9
|
+
from definite_sdk.message import DefiniteMessageClient
|
|
10
|
+
from definite_sdk.secret import DefiniteSecretStore
|
|
11
|
+
from definite_sdk.sql import DefiniteSqlClient
|
|
12
|
+
from definite_sdk.store import DefiniteKVStore
|
|
13
|
+
|
|
14
|
+
__version__ = "0.1.9"
|
|
15
|
+
__all__ = [
|
|
16
|
+
"DefiniteClient",
|
|
17
|
+
"DefiniteIntegrationStore",
|
|
18
|
+
"DefiniteMessageClient",
|
|
19
|
+
"DefiniteSecretStore",
|
|
20
|
+
"DefiniteSqlClient",
|
|
21
|
+
"DefiniteKVStore",
|
|
22
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from definite_sdk.integration import DefiniteIntegrationStore
|
|
5
|
+
from definite_sdk.message import DefiniteMessageClient
|
|
6
|
+
from definite_sdk.secret import DefiniteSecretStore
|
|
7
|
+
from definite_sdk.sql import DefiniteSqlClient
|
|
8
|
+
from definite_sdk.store import DefiniteKVStore
|
|
9
|
+
|
|
10
|
+
API_URL = "https://api.definite.app"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DefiniteClient:
|
|
14
|
+
"""Client for interacting with the Definite API."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, api_key: Optional[str] = None, api_url: str = API_URL):
|
|
17
|
+
"""Creates a definite client with the provided API key.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
api_key: API key for authentication. If not provided, will look for
|
|
21
|
+
DEFINITE_API_KEY or DEF_API_KEY environment variables.
|
|
22
|
+
api_url: Base URL for the Definite API.
|
|
23
|
+
|
|
24
|
+
See: https://docs.definite.app/definite-api for how to obtain an API key.
|
|
25
|
+
"""
|
|
26
|
+
if api_key is None:
|
|
27
|
+
api_key = os.getenv("DEFINITE_API_KEY") or os.getenv("DEF_API_KEY")
|
|
28
|
+
if not api_key:
|
|
29
|
+
raise ValueError(
|
|
30
|
+
"API key must be provided or set in DEFINITE_API_KEY "
|
|
31
|
+
"or DEF_API_KEY environment variable"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
self.api_key = api_key
|
|
35
|
+
self.api_url = api_url
|
|
36
|
+
|
|
37
|
+
def get_kv_store(self, name: str) -> DefiniteKVStore:
|
|
38
|
+
"""Initializes a key-value store with the provided name.
|
|
39
|
+
|
|
40
|
+
See DefiniteKVStore for more how to interact with the store.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
return DefiniteKVStore(name, self.api_key, self.api_url)
|
|
44
|
+
|
|
45
|
+
def get_secret_store(self) -> DefiniteSecretStore:
|
|
46
|
+
"""Initializes the secret store.
|
|
47
|
+
|
|
48
|
+
See DefiniteSecretStore for more how to interact with the store.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
return DefiniteSecretStore(self.api_key, self.api_url)
|
|
52
|
+
|
|
53
|
+
def get_integration_store(self) -> DefiniteIntegrationStore:
|
|
54
|
+
"""Initializes the integration store.
|
|
55
|
+
|
|
56
|
+
See DefiniteIntegrationStore for more how to interact with the store.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
return DefiniteIntegrationStore(self.api_key, self.api_url)
|
|
60
|
+
|
|
61
|
+
def get_sql_client(self) -> DefiniteSqlClient:
|
|
62
|
+
"""Initializes the SQL client for executing SQL queries.
|
|
63
|
+
|
|
64
|
+
See DefiniteSqlClient for more how to execute SQL queries.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
return DefiniteSqlClient(self.api_key, self.api_url)
|
|
68
|
+
|
|
69
|
+
# Alias methods for consistency
|
|
70
|
+
def kv_store(self, name: str) -> DefiniteKVStore:
|
|
71
|
+
"""Alias for get_kv_store."""
|
|
72
|
+
return self.get_kv_store(name)
|
|
73
|
+
|
|
74
|
+
def secret_store(self) -> DefiniteSecretStore:
|
|
75
|
+
"""Alias for get_secret_store."""
|
|
76
|
+
return self.get_secret_store()
|
|
77
|
+
|
|
78
|
+
def integration_store(self) -> DefiniteIntegrationStore:
|
|
79
|
+
"""Alias for get_integration_store."""
|
|
80
|
+
return self.get_integration_store()
|
|
81
|
+
|
|
82
|
+
def get_message_client(self) -> DefiniteMessageClient:
|
|
83
|
+
"""Initializes the message client for sending messages via various channels.
|
|
84
|
+
|
|
85
|
+
See DefiniteMessageClient for more how to send messages.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
return DefiniteMessageClient(self.api_key, self.api_url)
|
|
89
|
+
|
|
90
|
+
def message_client(self) -> DefiniteMessageClient:
|
|
91
|
+
"""Alias for get_message_client."""
|
|
92
|
+
return self.get_message_client()
|