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.
@@ -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()