unique_sdk 0.10.56__py3-none-any.whl → 0.10.62__py3-none-any.whl

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.
@@ -128,6 +128,7 @@ class AgenticTable(APIResource["AgenticTable"]):
128
128
  tableId: str
129
129
  rowOrder: int
130
130
  columnOrder: int
131
+ includeRowMetadata: NotRequired[bool]
131
132
 
132
133
  class SetActivityStatus(RequestOptions):
133
134
  tableId: str
@@ -210,6 +211,9 @@ class AgenticTable(APIResource["AgenticTable"]):
210
211
  ) -> "AgenticTableCell":
211
212
  """ """
212
213
  url = f"/magic-table/{params['tableId']}/cell?rowOrder={params['rowOrder']}&columnOrder={params['columnOrder']}"
214
+ params.pop("tableId")
215
+ params.pop("rowOrder")
216
+ params.pop("columnOrder")
213
217
  return cast(
214
218
  "AgenticTableCell",
215
219
  await cls._static_request_async(
@@ -217,7 +221,7 @@ class AgenticTable(APIResource["AgenticTable"]):
217
221
  url,
218
222
  user_id,
219
223
  company_id,
220
- params={},
224
+ params=params,
221
225
  ),
222
226
  )
223
227
 
@@ -133,6 +133,7 @@ class Content(APIResource["Content"]):
133
133
  uniqueIngestionMode: str
134
134
  vttConfig: Optional["Content.VttConfig"]
135
135
  wordReadMode: Optional[str]
136
+ hideInChat: Optional[bool]
136
137
 
137
138
  class Input(TypedDict):
138
139
  key: str
@@ -210,20 +211,23 @@ class Content(APIResource["Content"]):
210
211
  columnName: str
211
212
  content: str
212
213
 
213
- class MagicTableSheetTable(TypedDict):
214
+ class MagicTableRow(TypedDict):
214
215
  rowId: str
215
216
  columns: List["Content.MagicTableSheetTableColumn"]
217
+ context: NotRequired[str]
218
+ rowMetadata: NotRequired[str]
216
219
 
217
220
  class MagicTableSheetIngestionConfiguration(TypedDict):
218
221
  columnIdsInMetadata: List[str]
219
222
  columnIdsInChunkText: List[str]
220
223
 
221
224
  class MagicTableSheetIngestParams(TypedDict):
222
- data: List["Content.MagicTableSheetTable"]
225
+ data: List["Content.MagicTableRow"]
223
226
  ingestionConfiguration: "Content.MagicTableSheetIngestionConfiguration"
224
227
  metadata: Dict[str, Optional[str]]
225
228
  scopeId: str
226
229
  sheetName: str
230
+ context: NotRequired[str]
227
231
 
228
232
  class MagicTableSheetRowIdToContentId(TypedDict):
229
233
  rowId: str
@@ -47,10 +47,14 @@ class Message(APIResource["Message"]):
47
47
 
48
48
  class ModifyParams(RequestOptions):
49
49
  chatId: str
50
+ originalText: NotRequired[str | None]
50
51
  text: NotRequired[Optional["str"]]
51
- references: Optional[List["Message.Reference"]]
52
- debugInfo: Optional[Dict[str, Any]]
53
- completedAt: Optional[datetime]
52
+ references: NotRequired[List["Message.Reference"] | None]
53
+ gptRequest: NotRequired[Dict[str, Any] | None]
54
+ debugInfo: NotRequired[Dict[str, Any] | None]
55
+ startedStreamingAt: NotRequired[datetime | None]
56
+ stoppedStreamingAt: NotRequired[datetime | None]
57
+ completedAt: NotRequired[datetime | None]
54
58
 
55
59
  class DeleteParams(RequestOptions):
56
60
  chatId: str
@@ -61,21 +65,16 @@ class Message(APIResource["Message"]):
61
65
  class RetrieveParams(RequestOptions):
62
66
  chatId: str
63
67
 
64
- class CreateEventParams(RequestOptions):
68
+ class CreateEventParams(ModifyParams):
65
69
  messageId: str
66
- chatId: str
67
- originalText: NotRequired[str | None]
68
- text: NotRequired[str | None]
69
- references: NotRequired[List["Message.Reference"] | None]
70
- gptRequest: NotRequired[Dict[str, Any] | None]
71
- debugInfo: NotRequired[Dict[str, Any] | None]
72
- completedAt: NotRequired[datetime | None]
73
70
 
74
71
  chatId: str
75
72
  text: Optional[str]
76
73
  role: Literal["SYSTEM", "USER", "ASSISTANT"]
77
74
  gptRequest: Optional[Dict[str, Any]]
78
75
  debugInfo: Optional[Dict[str, Any]]
76
+ startedStreamingAt: Optional[datetime]
77
+ stoppedStreamingAt: Optional[datetime]
79
78
 
80
79
  @classmethod
81
80
  def list(
@@ -80,9 +80,11 @@ class Space(APIResource["Space"]):
80
80
  originalText: str | None
81
81
  role: Literal["SYSTEM", "USER", "ASSISTANT"]
82
82
  debugInfo: Optional[Dict[str, Any]]
83
+ gptRequest: Optional[Dict[str, Any]]
83
84
  completedAt: str | None
84
85
  createdAt: str | None
85
86
  updatedAt: str | None
87
+ startedStreamingAt: str | None
86
88
  stoppedStreamingAt: str | None
87
89
  references: Optional[List["Space.Reference"]]
88
90
  assessment: Optional[List["Space.Assessment"]]
@@ -26,6 +26,7 @@ class User(APIResource["User"]):
26
26
  take: NotRequired[Optional[int]]
27
27
  email: NotRequired[Optional[str]]
28
28
  displayName: NotRequired[Optional[str]]
29
+ userName: NotRequired[Optional[str]]
29
30
 
30
31
  class UpdateUserConfigurationParams(RequestOptions):
31
32
  """
@@ -34,6 +35,17 @@ class User(APIResource["User"]):
34
35
 
35
36
  userConfiguration: Dict[str, Any]
36
37
 
38
+ class UserGroup(TypedDict):
39
+ id: str
40
+ name: str
41
+ externalId: Optional[str]
42
+ parentId: Optional[str]
43
+ createdAt: str
44
+ updatedAt: str
45
+
46
+ class UserGroupsResponse(TypedDict):
47
+ groups: List["User.UserGroup"]
48
+
37
49
  class User(TypedDict):
38
50
  """
39
51
  Represents a user in the company.
@@ -147,3 +159,37 @@ class User(APIResource["User"]):
147
159
  params=params,
148
160
  ),
149
161
  )
162
+
163
+ @classmethod
164
+ def get_user_groups(
165
+ cls,
166
+ user_id: str,
167
+ company_id: str,
168
+ target_user_id: str,
169
+ ) -> "User.UserGroupsResponse":
170
+ return cast(
171
+ "User.UserGroupsResponse",
172
+ cls._static_request(
173
+ "get",
174
+ f"/users/{target_user_id}/groups",
175
+ user_id,
176
+ company_id,
177
+ ),
178
+ )
179
+
180
+ @classmethod
181
+ async def get_user_groups_async(
182
+ cls,
183
+ user_id: str,
184
+ company_id: str,
185
+ target_user_id: str,
186
+ ) -> "User.UserGroupsResponse":
187
+ return cast(
188
+ "User.UserGroupsResponse",
189
+ await cls._static_request_async(
190
+ "get",
191
+ f"/users/{target_user_id}/groups",
192
+ user_id,
193
+ company_id,
194
+ ),
195
+ )
@@ -1,10 +1,13 @@
1
1
  import asyncio
2
+ import warnings
2
3
  from typing import List, Literal
3
4
 
4
- from unique_sdk.api_resources._content import Content
5
5
  from unique_sdk.api_resources._message import Message
6
6
  from unique_sdk.api_resources._space import Space
7
7
  from unique_sdk.utils.file_io import upload_file
8
+ from unique_sdk.utils.file_io import (
9
+ wait_for_ingestion_completion as _wait_for_ingestion_completion,
10
+ )
8
11
 
9
12
 
10
13
  async def send_message_and_wait_for_completion(
@@ -116,7 +119,7 @@ async def chat_against_file(
116
119
  )
117
120
  content_id = upload_response.get("id")
118
121
 
119
- await wait_for_ingestion_completion(
122
+ await _wait_for_ingestion_completion(
120
123
  user_id=user_id,
121
124
  company_id=company_id,
122
125
  content_id=content_id,
@@ -159,23 +162,21 @@ async def wait_for_ingestion_completion(
159
162
  ):
160
163
  """
161
164
  Polls until the content ingestion is finished or the maximum wait time is reached and throws in case ingestion fails. The function assumes that the content exists.
165
+
166
+ .. deprecated::
167
+ Use :func:`unique_sdk.utils.file_io.wait_for_ingestion_completion` instead.
162
168
  """
163
- max_attempts = int(max_wait // poll_interval)
164
- for _ in range(max_attempts):
165
- searched_content = Content.search(
166
- user_id=user_id,
167
- company_id=company_id,
168
- where={"id": {"equals": content_id}},
169
- chatId=chat_id,
170
- includeFailedContent=True,
171
- )
172
- if searched_content:
173
- ingestion_state = searched_content[0].get("ingestionState")
174
- if ingestion_state == "FINISHED":
175
- return ingestion_state
176
- if isinstance(ingestion_state, str) and ingestion_state.startswith(
177
- "FAILED"
178
- ):
179
- raise RuntimeError(f"Ingestion failed with state: {ingestion_state}")
180
- await asyncio.sleep(poll_interval)
181
- raise TimeoutError("Timed out waiting for file ingestion to finish.")
169
+ warnings.warn(
170
+ "unique_sdk.utils.chat_in_space.wait_for_ingestion_completion is deprecated. "
171
+ "Use unique_sdk.utils.file_io.wait_for_ingestion_completion instead.",
172
+ DeprecationWarning,
173
+ stacklevel=2,
174
+ )
175
+ return await _wait_for_ingestion_completion(
176
+ user_id=user_id,
177
+ company_id=company_id,
178
+ content_id=content_id,
179
+ chat_id=chat_id,
180
+ poll_interval=poll_interval,
181
+ max_wait=max_wait,
182
+ )
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import os
2
3
  import tempfile
3
4
  from pathlib import Path
@@ -151,3 +152,35 @@ def download_content(
151
152
  raise Exception(f"Error downloading file: Status code {response.status_code}")
152
153
 
153
154
  return file_path
155
+
156
+
157
+ async def wait_for_ingestion_completion(
158
+ user_id: str,
159
+ company_id: str,
160
+ content_id: str,
161
+ chat_id: str | None = None,
162
+ poll_interval: float = 1.0,
163
+ max_wait: float = 60.0,
164
+ ):
165
+ """
166
+ Polls until the content ingestion is finished or the maximum wait time is reached and throws in case ingestion fails. The function assumes that the content exists.
167
+ """
168
+ max_attempts = int(max_wait // poll_interval)
169
+ for _ in range(max_attempts):
170
+ searched_content = Content.search(
171
+ user_id=user_id,
172
+ company_id=company_id,
173
+ where={"id": {"equals": content_id}},
174
+ chatId=chat_id,
175
+ includeFailedContent=True,
176
+ )
177
+ if searched_content:
178
+ ingestion_state = searched_content[0].get("ingestionState")
179
+ if ingestion_state == "FINISHED":
180
+ return ingestion_state
181
+ if isinstance(ingestion_state, str) and ingestion_state.startswith(
182
+ "FAILED"
183
+ ):
184
+ raise RuntimeError(f"Ingestion failed with state: {ingestion_state}")
185
+ await asyncio.sleep(poll_interval)
186
+ raise TimeoutError("Timed out waiting for file ingestion to finish.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_sdk
3
- Version: 0.10.56
3
+ Version: 0.10.62
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: Martin Fadler
@@ -28,6 +28,25 @@ All notable changes to this project will be documented in this file.
28
28
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
29
29
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
30
30
 
31
+ ## [0.10.62] - 2025-12-23
32
+ - Add get user gorups function and allow the get users function to filter by username.
33
+
34
+ ## [0.10.61] - 2025-12-22
35
+ - Add `displayInChat` field to ingestion config, allowing silent uploads to chat.
36
+
37
+ ## [0.10.60] - 2025-12-19
38
+ - Expose startedStreamingAt and gptRequest fields
39
+
40
+ ## [0.10.59] - 2025-12-19
41
+ - Add context field to MagicTableSheetIngestParams.
42
+ - Add rowMetadata and context fields to MagicTableRow.
43
+
44
+ ## [0.10.58] - 2025-12-16
45
+ - chore(deps): Bump urllib3 from 2.5.0 to 2.6.2
46
+
47
+ ## [0.10.57] - 2025-12-06
48
+ - Add description field on create chat completions params.
49
+
31
50
  ## [0.10.56] - 2025-12-05
32
51
  - Add description field on create chat completions params.
33
52
 
@@ -15,9 +15,9 @@ unique_sdk/_version.py,sha256=j4_tPC6t3enRds7LqiRuWSyfrYHfEo6CXIDARAWW98I,19
15
15
  unique_sdk/_webhook.py,sha256=GYxbUibQN_W4XlNTHaMIksT9FQJk4LJmlKcxOu3jqiU,2855
16
16
  unique_sdk/api_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  unique_sdk/api_resources/_acronyms.py,sha256=GIU1XH1flGWQYcpsFqTYwg4ioIGxVmb15tux84nmhEg,891
18
- unique_sdk/api_resources/_agentic_table.py,sha256=GN-GBgWEwRZOdKsx6DoHPZpjrr71PUGtyuJk20ETmFY,10208
18
+ unique_sdk/api_resources/_agentic_table.py,sha256=omdF4vbGCsjuQpPhuMUwaaGAb9nXscEUZsqUz3cz2AY,10353
19
19
  unique_sdk/api_resources/_chat_completion.py,sha256=ILCAffxkbkfh2iV9L4KKnfe80gZmT9pWfkNmf3mq68U,2172
20
- unique_sdk/api_resources/_content.py,sha256=vRynwj4QBZA1v2CVg_xbhmLqqh3m4cPGMoLeFZTaSYA,17543
20
+ unique_sdk/api_resources/_content.py,sha256=GT8vdCF1CygQay4lqacVQTQxPuLk94yzWoZpcd1G08U,17670
21
21
  unique_sdk/api_resources/_embedding.py,sha256=C6qak7cCUBMBINfPhgH8taCJZ9n6w1MUElqDJJ8dG10,1281
22
22
  unique_sdk/api_resources/_event.py,sha256=bpWF9vstdoAWbUzr-iiGP713ceP0zPk77GJXiImf9zg,374
23
23
  unique_sdk/api_resources/_folder.py,sha256=4I_b5GFGJUcRNcebCWcM8aDm0DQ6g6Y4JrkpUNxtJSc,16945
@@ -25,21 +25,21 @@ unique_sdk/api_resources/_group.py,sha256=8A8mSjhWuhFxBA2r_z7q-70miJ_ugz7NAffVwb
25
25
  unique_sdk/api_resources/_integrated.py,sha256=TxEKSYQZjZezBUk6kUgLvCgqgZXvgZR2IqHLieapKwQ,6204
26
26
  unique_sdk/api_resources/_llm_models.py,sha256=3Jn6MpxWgZ43Hze8JHd4_n27si5xmwd3JE8r8cEZq_M,1640
27
27
  unique_sdk/api_resources/_mcp.py,sha256=zKh0dyn0QnkKk57N2zlGVN_GQoxEp5T2CS38vVm6jQY,3341
28
- unique_sdk/api_resources/_message.py,sha256=tSS_jVwoAffBFH6RSClEnbRf48MleL7RMs3MnbNDq-E,10986
28
+ unique_sdk/api_resources/_message.py,sha256=wqPH3FdzutHLQXFErAzQYOddoeeE4jEBJr7yrPFYEHo,10986
29
29
  unique_sdk/api_resources/_message_assessment.py,sha256=SSfx6eW7zb_GKe8cFJzCqW-t-_eWEXxKP5cnIb0DhIc,2276
30
30
  unique_sdk/api_resources/_message_execution.py,sha256=7V_Qovu4vzoXDd2em0AgnAJC460RUX6AE4byztNPlvg,4556
31
31
  unique_sdk/api_resources/_message_log.py,sha256=_DifZ4Di7uKyzkP0i8rwu5IIiYZPCBp5lvE4gfTrTHw,4793
32
32
  unique_sdk/api_resources/_search.py,sha256=GQItZKoGNOVZfkLLltBmsRZYBIreRKU0lGW8Kgpj1_Q,1959
33
33
  unique_sdk/api_resources/_search_string.py,sha256=LZz2_QPZXV1NXucRR06dnDC2miK7J8XBY7dXX2xoDY4,1610
34
34
  unique_sdk/api_resources/_short_term_memory.py,sha256=vPRN-Y0WPx74E6y-A3LocGc0TxJdzT-xGL66WzZwKRg,2820
35
- unique_sdk/api_resources/_space.py,sha256=YfAywlTl0BUtl3U6Zml9CRyWqhrFeKCoo15mYmynErw,9380
36
- unique_sdk/api_resources/_user.py,sha256=CAIT1GOk-knaLLIofl73O3WVGc_zeUv5XjqhuYcgD50,3522
35
+ unique_sdk/api_resources/_space.py,sha256=cs5Z3x5vzfJFcxUhVuh2GQSGmP0ygzumwaNPOwJ8upI,9464
36
+ unique_sdk/api_resources/_user.py,sha256=XGlE3SDtv-0qs9boT-ts6F2Cxq8RXAT5OCrvY5nOCx8,4677
37
37
  unique_sdk/utils/chat_history.py,sha256=5UqL9hF1O9pV7skbNOlEibF5rHdYsmG3m5-YEPUowOs,3037
38
- unique_sdk/utils/chat_in_space.py,sha256=e_Ny03eB7Q8oijdUR_sPlFTIgq2rsCbSR-Sin8jnxM8,6066
39
- unique_sdk/utils/file_io.py,sha256=lskRULIh7qExK26o_1YqRs0f5mqJHTS9m_mdxlsVo4s,4497
38
+ unique_sdk/utils/chat_in_space.py,sha256=mBH4W-Jb8wgGCYV3m12LvoLjTE56xdwUTC-ghMupkSs,5889
39
+ unique_sdk/utils/file_io.py,sha256=z0VdAOtrkU-tMq2v-nogeHtBku3TtnM5eJDHAR6A0-w,5721
40
40
  unique_sdk/utils/sources.py,sha256=DoxxhMLcLhmDfNarjXa41H4JD2GSSDywr71hiC-4pYc,4952
41
41
  unique_sdk/utils/token.py,sha256=AzKuAA1AwBtnvSFxGcsHLpxXr_wWE5Mj4jYBbOz2ljA,1740
42
- unique_sdk-0.10.56.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
43
- unique_sdk-0.10.56.dist-info/METADATA,sha256=TRZBMVYh2i5ZRDBbODnEaJn_WWJOurtgoV25fwgJUBY,10484
44
- unique_sdk-0.10.56.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
45
- unique_sdk-0.10.56.dist-info/RECORD,,
42
+ unique_sdk-0.10.62.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
43
+ unique_sdk-0.10.62.dist-info/METADATA,sha256=zh-NI8rTy0kYmX1B4A_Xs18snScEUnwMHaZXzCeh_v0,11079
44
+ unique_sdk-0.10.62.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
45
+ unique_sdk-0.10.62.dist-info/RECORD,,