unique_sdk 0.10.17__py3-none-any.whl → 0.10.19__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.
- unique_sdk/api_resources/_content.py +4 -58
- unique_sdk/utils/chat_in_space.py +15 -2
- {unique_sdk-0.10.17.dist-info → unique_sdk-0.10.19.dist-info}/METADATA +18 -43
- {unique_sdk-0.10.17.dist-info → unique_sdk-0.10.19.dist-info}/RECORD +6 -6
- {unique_sdk-0.10.17.dist-info → unique_sdk-0.10.19.dist-info}/LICENSE +0 -0
- {unique_sdk-0.10.17.dist-info → unique_sdk-0.10.19.dist-info}/WHEEL +0 -0
@@ -12,7 +12,6 @@ from typing import (
|
|
12
12
|
|
13
13
|
from typing_extensions import NotRequired, Unpack
|
14
14
|
|
15
|
-
import unique_sdk
|
16
15
|
from unique_sdk._api_resource import APIResource
|
17
16
|
from unique_sdk._request_options import RequestOptions
|
18
17
|
|
@@ -130,9 +129,7 @@ class Content(APIResource["Content"]):
|
|
130
129
|
|
131
130
|
class UpdateParams(RequestOptions):
|
132
131
|
contentId: str | None = None
|
133
|
-
filePath: str | None = None
|
134
132
|
ownerId: str | None = None
|
135
|
-
parentFolderPath: str | None = None
|
136
133
|
title: str | None = None
|
137
134
|
|
138
135
|
class Chunk(TypedDict):
|
@@ -168,7 +165,6 @@ class Content(APIResource["Content"]):
|
|
168
165
|
|
169
166
|
class DeleteParams(RequestOptions):
|
170
167
|
contentId: NotRequired[str]
|
171
|
-
filePath: NotRequired[str]
|
172
168
|
chatId: NotRequired[str]
|
173
169
|
|
174
170
|
class DeleteResponse(TypedDict):
|
@@ -406,28 +402,11 @@ class Content(APIResource["Content"]):
|
|
406
402
|
company_id: str,
|
407
403
|
**params: Unpack["Content.UpdateParams"],
|
408
404
|
) -> "Content.ContentInfo":
|
409
|
-
content_id = cls.resolve_content_id_from_file_path(
|
410
|
-
user_id,
|
411
|
-
company_id,
|
412
|
-
params.get("contentId"),
|
413
|
-
params.get("filePath"),
|
414
|
-
)
|
415
|
-
owner_id = unique_sdk.Folder.resolve_scope_id_from_folder_path(
|
416
|
-
user_id,
|
417
|
-
company_id,
|
418
|
-
params.get("ownerId"),
|
419
|
-
params.get("parentFolderPath"),
|
420
|
-
)
|
421
|
-
params.pop("contentId", None)
|
422
|
-
params.pop("filePath", None)
|
423
|
-
params.pop("parentFolderPath", None)
|
424
|
-
params["ownerId"] = owner_id
|
425
|
-
|
426
405
|
return cast(
|
427
406
|
"Content.ContentInfo",
|
428
407
|
cls._static_request(
|
429
408
|
"patch",
|
430
|
-
f"/content/{
|
409
|
+
f"/content/{params.get('contentId')}",
|
431
410
|
user_id,
|
432
411
|
company_id,
|
433
412
|
params=params,
|
@@ -441,28 +420,11 @@ class Content(APIResource["Content"]):
|
|
441
420
|
company_id: str,
|
442
421
|
**params: Unpack["Content.UpdateParams"],
|
443
422
|
) -> "Content.ContentInfo":
|
444
|
-
content_id = cls.resolve_content_id_from_file_path(
|
445
|
-
user_id,
|
446
|
-
company_id,
|
447
|
-
params.get("contentId"),
|
448
|
-
params.get("filePath"),
|
449
|
-
)
|
450
|
-
owner_id = unique_sdk.Folder.resolve_scope_id_from_folder_path(
|
451
|
-
user_id,
|
452
|
-
company_id,
|
453
|
-
params.get("ownerId"),
|
454
|
-
params.get("parentFolderPath"),
|
455
|
-
)
|
456
|
-
params.pop("contentId", None)
|
457
|
-
params.pop("filePath", None)
|
458
|
-
params.pop("parentFolderPath", None)
|
459
|
-
params["ownerId"] = owner_id
|
460
|
-
|
461
423
|
return cast(
|
462
424
|
"Content.ContentInfo",
|
463
425
|
await cls._static_request_async(
|
464
426
|
"patch",
|
465
|
-
f"/content/{
|
427
|
+
f"/content/{params.get('contentId')}",
|
466
428
|
user_id,
|
467
429
|
company_id,
|
468
430
|
params=params,
|
@@ -479,20 +441,12 @@ class Content(APIResource["Content"]):
|
|
479
441
|
"""
|
480
442
|
Deletes a content by its id or file path.
|
481
443
|
"""
|
482
|
-
content_id = cls.resolve_content_id_from_file_path(
|
483
|
-
user_id,
|
484
|
-
company_id,
|
485
|
-
params.get("contentId"),
|
486
|
-
params.get("filePath"),
|
487
|
-
)
|
488
|
-
params.pop("contentId", None)
|
489
|
-
params.pop("filePath", None)
|
490
444
|
|
491
445
|
return cast(
|
492
446
|
"Content.DeleteResponse",
|
493
447
|
cls._static_request(
|
494
448
|
"delete",
|
495
|
-
f"/content/{
|
449
|
+
f"/content/{params.get('contentId')}",
|
496
450
|
user_id,
|
497
451
|
company_id,
|
498
452
|
params=params,
|
@@ -509,20 +463,12 @@ class Content(APIResource["Content"]):
|
|
509
463
|
"""
|
510
464
|
Async deletes a content by its id or file path.
|
511
465
|
"""
|
512
|
-
content_id = cls.resolve_content_id_from_file_path(
|
513
|
-
user_id,
|
514
|
-
company_id,
|
515
|
-
params.get("contentId"),
|
516
|
-
params.get("filePath"),
|
517
|
-
)
|
518
|
-
params.pop("contentId", None)
|
519
|
-
params.pop("filePath", None)
|
520
466
|
|
521
467
|
return cast(
|
522
468
|
"Content.DeleteResponse",
|
523
469
|
await cls._static_request_async(
|
524
470
|
"delete",
|
525
|
-
f"/content/{
|
471
|
+
f"/content/{params.get('contentId')}",
|
526
472
|
user_id,
|
527
473
|
company_id,
|
528
474
|
params=params,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import asyncio
|
2
|
-
from typing import List
|
2
|
+
from typing import List, Literal
|
3
3
|
|
4
4
|
from unique_sdk.api_resources._content import Content
|
5
|
+
from unique_sdk.api_resources._message import Message
|
5
6
|
from unique_sdk.api_resources._space import Space
|
6
7
|
from unique_sdk.utils.file_io import upload_file
|
7
8
|
|
@@ -16,6 +17,7 @@ async def send_message_and_wait_for_completion(
|
|
16
17
|
chat_id: str = None,
|
17
18
|
poll_interval: float = 1.0,
|
18
19
|
max_wait: float = 60.0,
|
20
|
+
stop_condition: Literal["stoppedStreamingAt", "completedAt"] = "stoppedStreamingAt",
|
19
21
|
) -> "Space.Message":
|
20
22
|
"""
|
21
23
|
Sends a prompt asynchronously and polls for completion. (until stoppedStreamingAt is not None)
|
@@ -27,6 +29,7 @@ async def send_message_and_wait_for_completion(
|
|
27
29
|
text: The prompt text.
|
28
30
|
poll_interval: Seconds between polls.
|
29
31
|
max_wait: Maximum seconds to wait for completion.
|
32
|
+
stop_condition: Defines when to expect a response back, when the assistant stop streaming or when it completes the message. (default: "stoppedStreamingAt")
|
30
33
|
**kwargs: Additional parameters for the prompt.
|
31
34
|
|
32
35
|
Returns:
|
@@ -42,11 +45,21 @@ async def send_message_and_wait_for_completion(
|
|
42
45
|
scopeRules=scope_rules,
|
43
46
|
)
|
44
47
|
chat_id = response.get("chatId")
|
48
|
+
message_id = response.get("id")
|
45
49
|
|
46
50
|
max_attempts = int(max_wait // poll_interval)
|
47
51
|
for _ in range(max_attempts):
|
48
52
|
answer = Space.get_latest_message(user_id, company_id, chat_id)
|
49
|
-
if answer.get(
|
53
|
+
if answer.get(stop_condition) is not None:
|
54
|
+
try:
|
55
|
+
user_message = Message.retrieve(
|
56
|
+
user_id, company_id, message_id, chatId=chat_id
|
57
|
+
)
|
58
|
+
debug_info = user_message.get("debugInfo")
|
59
|
+
answer["debugInfo"] = debug_info
|
60
|
+
except Exception as e:
|
61
|
+
print(f"Failed to load debug info from user message: {e}")
|
62
|
+
|
50
63
|
return answer
|
51
64
|
await asyncio.sleep(poll_interval)
|
52
65
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: unique_sdk
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.19
|
4
4
|
Summary:
|
5
5
|
License: MIT
|
6
6
|
Author: Martin Fadler
|
@@ -556,32 +556,19 @@ Allows you to ingest a magic table sheet, each row is processed and converted in
|
|
556
556
|
|
557
557
|
#### `unique_sdk.Content.update` (Compatible with release >.36)
|
558
558
|
|
559
|
-
Allows you to update a file specified by its `contentId
|
559
|
+
Allows you to update a file specified by its `contentId`.
|
560
560
|
|
561
|
-
- `contentId`
|
562
|
-
- `filePath` optional if `contentId` is provided, the absolute path of the file to be updated
|
561
|
+
- `contentId` the id of the file to be updated
|
563
562
|
|
564
563
|
Currently, the following updates are supported:
|
565
564
|
|
566
565
|
Title update:
|
567
566
|
- `title` optional, allows updating the title of the folder
|
568
567
|
|
569
|
-
Move the file to a different folder. this can be done by specifying either the `ownerId
|
568
|
+
Move the file to a different folder. this can be done by specifying either the `ownerId`.
|
570
569
|
- `ownerId` optional, allows moving the file to a different folder. Represents the new folder for the file and it should be the id of a folder e.g.: `scope_dhjfieurfloakmdle`.
|
571
|
-
- `parentFolderPath` optional, allows moving the file to a different folder. Represents the path new folder for the file.
|
572
570
|
|
573
571
|
|
574
|
-
Example of updating the title of a file specified by its path.
|
575
|
-
|
576
|
-
```python
|
577
|
-
unique_sdk.Content.update(
|
578
|
-
user_id=user_id,
|
579
|
-
company_id=company_id,
|
580
|
-
filePath="/Company/finance/january.xls",
|
581
|
-
title="Revision Deck"
|
582
|
-
)
|
583
|
-
```
|
584
|
-
|
585
572
|
Example of moving a file specified by its content id.
|
586
573
|
|
587
574
|
```python
|
@@ -605,25 +592,12 @@ unique_sdk.Content.update(
|
|
605
592
|
)
|
606
593
|
```
|
607
594
|
|
608
|
-
Example of moving a file to a folder specified by its path.
|
609
|
-
|
610
|
-
```python
|
611
|
-
unique_sdk.Content.update(
|
612
|
-
user_id=user_id,
|
613
|
-
company_id=company_id,
|
614
|
-
contentId="cont_ok2343q5owbce80w78hudawu5",
|
615
|
-
ownerId="scope_e68yz5asho7glfh7c7d041el",
|
616
|
-
parentFolderPath="/Company/Revisions"
|
617
|
-
)
|
618
|
-
```
|
619
|
-
|
620
595
|
#### `unique_sdk.Content.delete` (Compatible with release >.36)
|
621
596
|
|
622
|
-
Allows you to delete a file by its `contentId
|
597
|
+
Allows you to delete a file by its `contentId`. If the file is part of a chat, the `chatId` also needs do be set.
|
623
598
|
|
624
|
-
- `contentId`
|
599
|
+
- `contentId` the id of the file to be deleted
|
625
600
|
- `chatId` optional, the id of the chat where the file is. Only needed if the file is part of a chat
|
626
|
-
- `filePath` optional if `contentId` is provided, the absolute path of the file to be deleted
|
627
601
|
|
628
602
|
Example of deleting a file from a chat.
|
629
603
|
|
@@ -636,16 +610,6 @@ unique_sdk.Content.delete(
|
|
636
610
|
)
|
637
611
|
```
|
638
612
|
|
639
|
-
Example of deleting a file by its path.
|
640
|
-
|
641
|
-
```python
|
642
|
-
unique_sdk.Content.delete(
|
643
|
-
user_id=user_id,
|
644
|
-
company_id=company_id,
|
645
|
-
filePath="/Company/finance/january.xls",
|
646
|
-
)
|
647
|
-
```
|
648
|
-
|
649
613
|
### Message
|
650
614
|
|
651
615
|
#### `unique_sdk.Message.list`
|
@@ -1502,11 +1466,13 @@ The script sends a prompt asynchronously and continuously polls for completion,
|
|
1502
1466
|
- `chat_id`: The ID of the chat where the message should be sent. If omitted, a new chat will be created.
|
1503
1467
|
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
1504
1468
|
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
1469
|
+
- `stop_condition`: Defines when to expect a response back, when the assistant stop streaming or when it completes the message. (default: "stoppedStreamingAt")
|
1505
1470
|
|
1506
1471
|
The script ensures you can flexibly interact with spaces in new or ongoing chats, with fine-grained control over tools, context, and polling behavior.
|
1507
1472
|
|
1508
1473
|
```python
|
1509
|
-
|
1474
|
+
from unique_sdk.utils.chat_in_space import send_message_and_wait_for_completion
|
1475
|
+
latest_message = await send_message_and_wait_for_completion(
|
1510
1476
|
user_id=user_id,
|
1511
1477
|
company_id=company_id,
|
1512
1478
|
assistant_id=assistant_id,
|
@@ -1533,6 +1499,7 @@ latest_message = await unique_sdk.utils.chat_in_space.send_message_and_wait_for_
|
|
1533
1499
|
}
|
1534
1500
|
]
|
1535
1501
|
},
|
1502
|
+
stop_condition = "completedAt" # If not specified, stoppedStreamingAt will be set by default
|
1536
1503
|
)
|
1537
1504
|
```
|
1538
1505
|
|
@@ -1608,6 +1575,14 @@ All notable changes to this project will be documented in this file.
|
|
1608
1575
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
1609
1576
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
1610
1577
|
|
1578
|
+
## [0.10.19] - 2025-09-02
|
1579
|
+
- Improve `send_message_and_wait_for_completion`:
|
1580
|
+
- Add option to select stop_condition `["stoppedStreamingAt", "completedAt"]`.
|
1581
|
+
- Load `debugInfo` from `last_user_message` for better developer experience.
|
1582
|
+
|
1583
|
+
## [0.10.18] - 2025-09-02
|
1584
|
+
- Temporarily remove support for update and delete files by filePath.
|
1585
|
+
|
1611
1586
|
## [0.10.17] - 2025-09-01
|
1612
1587
|
- Add function to update a file
|
1613
1588
|
|
@@ -17,7 +17,7 @@ unique_sdk/api_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
17
17
|
unique_sdk/api_resources/_acronyms.py,sha256=GIU1XH1flGWQYcpsFqTYwg4ioIGxVmb15tux84nmhEg,891
|
18
18
|
unique_sdk/api_resources/_agentic_table.py,sha256=8-_f7t-m_iiiOj2835iESoxz91YRxl4-tkxpzQbgdcI,9958
|
19
19
|
unique_sdk/api_resources/_chat_completion.py,sha256=ILCAffxkbkfh2iV9L4KKnfe80gZmT9pWfkNmf3mq68U,2172
|
20
|
-
unique_sdk/api_resources/_content.py,sha256=
|
20
|
+
unique_sdk/api_resources/_content.py,sha256=Vi-wZ-T5f-OqBGXkA3B9dALoFHer5F8LAQlc5x6pcls,14109
|
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=mIyWaxJtIHlDLPFZ0FY1U9b3dmtmIcjDEbgOZtLA-DI,12871
|
@@ -32,11 +32,11 @@ unique_sdk/api_resources/_search_string.py,sha256=4Idw6exgZdA8qksz9WkiA68k1hTU-7
|
|
32
32
|
unique_sdk/api_resources/_short_term_memory.py,sha256=vPRN-Y0WPx74E6y-A3LocGc0TxJdzT-xGL66WzZwKRg,2820
|
33
33
|
unique_sdk/api_resources/_space.py,sha256=6789zLwkoZqrEESiTJIBVaNi8kAKAZnqR0KMmW1AzgI,4905
|
34
34
|
unique_sdk/utils/chat_history.py,sha256=5UqL9hF1O9pV7skbNOlEibF5rHdYsmG3m5-YEPUowOs,3037
|
35
|
-
unique_sdk/utils/chat_in_space.py,sha256=
|
35
|
+
unique_sdk/utils/chat_in_space.py,sha256=NrH9e2lvXtj_oePG0RWUqFoTanMblF8-VgtnVfszPS8,5949
|
36
36
|
unique_sdk/utils/file_io.py,sha256=YY8B7VJcTLOPmCXByiOfNerXGlAtjCC5EVNmAbQJ3dQ,4306
|
37
37
|
unique_sdk/utils/sources.py,sha256=DoxxhMLcLhmDfNarjXa41H4JD2GSSDywr71hiC-4pYc,4952
|
38
38
|
unique_sdk/utils/token.py,sha256=AzKuAA1AwBtnvSFxGcsHLpxXr_wWE5Mj4jYBbOz2ljA,1740
|
39
|
-
unique_sdk-0.10.
|
40
|
-
unique_sdk-0.10.
|
41
|
-
unique_sdk-0.10.
|
42
|
-
unique_sdk-0.10.
|
39
|
+
unique_sdk-0.10.19.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
|
40
|
+
unique_sdk-0.10.19.dist-info/METADATA,sha256=xppurAY1RbWZ-Z8BlMws7i_yZZhYY04pqxDj676FTpU,54448
|
41
|
+
unique_sdk-0.10.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
42
|
+
unique_sdk-0.10.19.dist-info/RECORD,,
|
File without changes
|
File without changes
|