definite-sdk 0.1.11__tar.gz → 0.1.14__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: definite-sdk
3
- Version: 0.1.11
3
+ Version: 0.1.14
4
4
  Summary: Definite SDK for Python
5
5
  License: MIT
6
6
  Author: Definite
@@ -11,7 +11,7 @@ from definite_sdk.secret import DefiniteSecretStore
11
11
  from definite_sdk.sql import DefiniteSqlClient
12
12
  from definite_sdk.store import DefiniteKVStore
13
13
 
14
- __version__ = "0.1.9"
14
+ __version__ = "0.1.14"
15
15
  __all__ = [
16
16
  "DefiniteClient",
17
17
  "DefiniteIntegrationStore",
@@ -19,4 +19,4 @@ __all__ = [
19
19
  "DefiniteSecretStore",
20
20
  "DefiniteSqlClient",
21
21
  "DefiniteKVStore",
22
- ]
22
+ ]
@@ -69,36 +69,45 @@ class DefiniteClient:
69
69
 
70
70
  def attach_ducklake(self, alias: str = "lake") -> str:
71
71
  """Generates SQL statements to attach DuckLake to a DuckDB connection.
72
-
72
+
73
73
  This method fetches the team's DuckLake integration credentials and generates
74
74
  the necessary SQL statements to create a GCS secret and attach DuckLake.
75
-
75
+
76
76
  Args:
77
77
  alias: The alias name for the attached DuckLake database (default: "lake")
78
-
78
+
79
79
  Returns:
80
80
  str: SQL statements to execute for attaching DuckLake
81
-
81
+
82
82
  Example:
83
83
  >>> client = DefiniteClient(os.environ["DEFINITE_API_KEY"])
84
84
  >>> sql = client.attach_ducklake()
85
85
  >>> conn.execute(sql)
86
86
  """
87
87
  # Fetch DuckLake integration details
88
- response = requests.get(
89
- f"{self.api_url}/v1/api/integration/DuckLake",
90
- headers={"Authorization": f"Bearer {self.api_key}"},
91
- )
92
- response.raise_for_status()
93
- dl_integration = response.json()
94
-
88
+ try:
89
+ response = requests.get(
90
+ f"{self.api_url}/v1/api/integration/Ducklake",
91
+ headers={"Authorization": f"Bearer {self.api_key}"},
92
+ )
93
+ response.raise_for_status()
94
+ dl_integration = response.json()
95
+ except requests.exceptions.HTTPError as e:
96
+ if response.status_code == 404:
97
+ raise ValueError(
98
+ "DuckLake integration not found. Please ensure you have a DuckLake integration "
99
+ "configured in your Definite account at https://ui.definite.app"
100
+ ) from e
101
+ else:
102
+ raise
103
+
95
104
  # Generate SQL statements
96
105
  create_secret_sql = f"""CREATE SECRET (
97
106
  TYPE gcs,
98
107
  KEY_ID '{dl_integration['gcs_access_key_id']}',
99
108
  SECRET '{dl_integration['gcs_secret_access_key']}'
100
109
  );"""
101
-
110
+
102
111
  # Build PostgreSQL connection string
103
112
  pg_conn_str = (
104
113
  f"postgresql://{dl_integration['pg_user']}:"
@@ -107,13 +116,13 @@ class DefiniteClient:
107
116
  f"{dl_integration['pg_port']}/"
108
117
  f"{dl_integration['pg_database']}"
109
118
  )
110
-
119
+
111
120
  attach_sql = (
112
121
  f"ATTACH 'ducklake:postgres:{pg_conn_str}' AS {alias} "
113
122
  f"(DATA_PATH 'gs://{dl_integration['gcs_bucket_path']}', "
114
123
  f"METADATA_SCHEMA '{dl_integration['pg_schema']}');"
115
124
  )
116
-
125
+
117
126
  return f"{create_secret_sql}\n\n{attach_sql}"
118
127
 
119
128
  # Alias methods for consistency
@@ -62,7 +62,7 @@ class DefiniteIntegrationStore:
62
62
  def lookup_duckdb_integration(self) -> Optional[Tuple[str, str]]:
63
63
  """
64
64
  Look up the team's DuckDB integration.
65
-
65
+
66
66
  Note: Currently, the API only returns extractor (source) integrations.
67
67
  Destination integrations like DuckDB are not yet exposed through this endpoint.
68
68
  This method is provided for future compatibility when the API is updated.
@@ -21,7 +21,7 @@ class DefiniteMessageClient:
21
21
  ... to="C0920MVPWFN", # channel_id
22
22
  ... content="Hello from Definite SDK!"
23
23
  ... )
24
-
24
+
25
25
  >>> # Send a Slack message with blocks and thread
26
26
  >>> result = message_client.send_message(
27
27
  ... channel="slack",
@@ -53,7 +53,7 @@ class DefiniteMessageClient:
53
53
  subject: Optional[str] = None,
54
54
  blocks: Optional[List[Dict[str, Any]]] = None,
55
55
  thread_ts: Optional[str] = None,
56
- **kwargs: Any
56
+ **kwargs: Any,
57
57
  ) -> Dict[str, Any]:
58
58
  """
59
59
  Sends a message through the specified channel.
@@ -83,7 +83,7 @@ class DefiniteMessageClient:
83
83
  ... to="C0920MVPWFN",
84
84
  ... content="Hello team!"
85
85
  ... )
86
-
86
+
87
87
  >>> # Slack message with blocks
88
88
  >>> result = message_client.send_message(
89
89
  ... channel="slack",
@@ -97,7 +97,7 @@ class DefiniteMessageClient:
97
97
  ... )
98
98
  """
99
99
  channel_lower = channel.lower()
100
-
100
+
101
101
  if channel_lower == "slack":
102
102
  return self._send_slack_message(
103
103
  integration_id=integration_id,
@@ -105,7 +105,7 @@ class DefiniteMessageClient:
105
105
  text=content,
106
106
  blocks=blocks,
107
107
  thread_ts=thread_ts,
108
- **kwargs
108
+ **kwargs,
109
109
  )
110
110
  else:
111
111
  raise ValueError(f"Unsupported channel: {channel}")
@@ -117,7 +117,7 @@ class DefiniteMessageClient:
117
117
  text: str,
118
118
  blocks: Optional[List[Dict[str, Any]]] = None,
119
119
  thread_ts: Optional[str] = None,
120
- **kwargs: Any
120
+ **kwargs: Any,
121
121
  ) -> Dict[str, Any]:
122
122
  """
123
123
  Internal method to send a Slack message.
@@ -134,18 +134,18 @@ class DefiniteMessageClient:
134
134
  Dict[str, Any]: The API response.
135
135
  """
136
136
  url = f"{self._message_url}/slack/message"
137
-
137
+
138
138
  payload = {
139
139
  "integration_id": integration_id,
140
140
  "channel_id": channel_id,
141
- "text": text
141
+ "text": text,
142
142
  }
143
-
143
+
144
144
  if blocks:
145
145
  payload["blocks"] = blocks
146
146
  if thread_ts:
147
147
  payload["thread_ts"] = thread_ts
148
-
148
+
149
149
  # Add any additional kwargs to the payload
150
150
  payload.update(kwargs)
151
151
 
@@ -164,7 +164,7 @@ class DefiniteMessageClient:
164
164
  text: str,
165
165
  blocks: Optional[List[Dict[str, Any]]] = None,
166
166
  thread_ts: Optional[str] = None,
167
- **kwargs: Any
167
+ **kwargs: Any,
168
168
  ) -> Dict[str, Any]:
169
169
  """
170
170
  Convenience method to send a Slack message directly.
@@ -195,5 +195,5 @@ class DefiniteMessageClient:
195
195
  content=text,
196
196
  blocks=blocks,
197
197
  thread_ts=thread_ts,
198
- **kwargs
199
- )
198
+ **kwargs,
199
+ )
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional, Union
1
+ from typing import Any, Dict, Optional
2
2
 
3
3
  import requests
4
4
 
@@ -31,7 +31,9 @@ class DefiniteSqlClient:
31
31
  ... "timeDimensions": [{"dimension": "sales.date", "granularity": "month"}],
32
32
  ... "limit": 1000
33
33
  ... }
34
- >>> result = sql_client.execute_cube_query(cube_query, integration_id="my_cube_integration")
34
+ >>> result = sql_client.execute_cube_query(
35
+ ... cube_query, integration_id="my_cube_integration"
36
+ ... )
35
37
  >>> print(result)
36
38
  """
37
39
 
@@ -46,11 +48,7 @@ class DefiniteSqlClient:
46
48
  self._api_key = api_key
47
49
  self._sql_url = api_url + SQL_ENDPOINT
48
50
 
49
- def execute(
50
- self,
51
- sql: str,
52
- integration_id: Optional[str] = None
53
- ) -> Dict[str, Any]:
51
+ def execute(self, sql: str, integration_id: Optional[str] = None) -> Dict[str, Any]:
54
52
  """
55
53
  Executes a SQL query against a database integration.
56
54
 
@@ -69,7 +67,7 @@ class DefiniteSqlClient:
69
67
  >>> result = sql_client.execute("SELECT COUNT(*) FROM users")
70
68
  >>> print(result)
71
69
  """
72
- payload = {"sql": sql}
70
+ payload: Dict[str, Any] = {"sql": sql}
73
71
  if integration_id:
74
72
  payload["integration_id"] = integration_id
75
73
 
@@ -82,11 +80,12 @@ class DefiniteSqlClient:
82
80
  return response.json()
83
81
 
84
82
  def execute_cube_query(
85
- self,
86
- cube_query: Dict[str, Any],
83
+ self,
84
+ cube_query: Dict[str, Any],
87
85
  integration_id: Optional[str] = None,
88
86
  persist: bool = True,
89
87
  invalidate: bool = False,
88
+ raw: bool = False,
90
89
  ) -> Dict[str, Any]:
91
90
  """
92
91
  Executes a Cube query against a Cube integration.
@@ -97,6 +96,7 @@ class DefiniteSqlClient:
97
96
  If not provided, the default integration will be used.
98
97
  persist (bool): Whether to persist the query result to the cache.
99
98
  invalidate (bool): Whether to invalidate the cached result.
99
+ raw (bool): Whether to return raw/unformatted cube results.
100
100
 
101
101
  Returns:
102
102
  Dict[str, Any]: The query result as returned by the API.
@@ -110,24 +110,38 @@ class DefiniteSqlClient:
110
110
  ... "measures": ["sales.total_amount"],
111
111
  ... "timeDimensions": [{
112
112
  ... "dimension": "sales.date",
113
- ... "granularity": "month"
113
+ ... "granularity": "month",
114
114
  ... }],
115
115
  ... "limit": 1000
116
116
  ... }
117
- >>> result = sql_client.execute_cube_query(cube_query, "my_cube_integration")
117
+ >>> result = sql_client.execute_cube_query(
118
+ ... cube_query, "my_cube_integration"
119
+ ... )
118
120
  >>> print(result)
121
+
122
+ >>> # To get raw/unformatted results:
123
+ >>> raw_result = sql_client.execute_cube_query(
124
+ ... cube_query, "my_cube_integration", raw=True
125
+ ... )
126
+ >>> print(raw_result)
119
127
  """
120
- payload = {"cube_query": cube_query}
128
+ payload: Dict[str, Any] = {"cube_query": cube_query}
121
129
  if integration_id:
122
130
  payload["integration_id"] = integration_id
123
131
  if persist:
124
132
  payload["persist"] = persist
125
133
  if invalidate:
126
134
  payload["invalidate"] = invalidate
135
+
136
+ # Build URL with query parameters
137
+ url = self._sql_url
138
+ if raw:
139
+ url += "?raw=true"
140
+
127
141
  response = requests.post(
128
- self._sql_url,
142
+ url,
129
143
  json=payload,
130
144
  headers={"Authorization": "Bearer " + self._api_key},
131
145
  )
132
146
  response.raise_for_status()
133
- return response.json()
147
+ return response.json()
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "definite-sdk"
3
- version = "0.1.11"
3
+ version = "0.1.14"
4
4
  description = "Definite SDK for Python"
5
5
  authors = ["Definite <hello@definite.app>"]
6
6
  license = "MIT"
File without changes
File without changes