unique_sdk 0.9.23__py3-none-any.whl → 0.9.28__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.

Potentially problematic release.


This version of unique_sdk might be problematic. Click here for more details.

@@ -65,8 +65,38 @@ class Content(APIResource["Content"]):
65
65
  where: "Content.ContentWhereInput"
66
66
  chatId: NotRequired[str]
67
67
 
68
- class IngestionConfig(TypedDict):
68
+ class ContentInfoParams(TypedDict):
69
+ """
70
+ Parameters for the content info endpoint.
71
+ This is used to retrieve information about content based on various filters.
72
+ """
73
+
74
+ metadataFilter: dict
75
+ skip: int | None
76
+ take: int | None
77
+
78
+ class CustomApiOptions(TypedDict):
79
+ apiIdentifier: str
80
+ apiPayload: Optional[str]
81
+ customisationType: str
82
+
83
+ class VttConfig(TypedDict, total=False):
84
+ languageModel: Optional[str]
85
+
86
+ class IngestionConfig(TypedDict, total=False):
87
+ chunkMaxTokens: Optional[int]
88
+ chunkMaxTokensOnePager: Optional[int]
89
+ chunkMinTokens: Optional[int]
90
+ chunkStrategy: Optional[str]
91
+ customApiOptions: Optional[List["Content.CustomApiOptions"]]
92
+ documentMinTokens: Optional[int]
93
+ excelReadMode: Optional[str]
94
+ jpgReadMode: Optional[str]
95
+ pdfReadMode: Optional[str]
96
+ pptReadMode: Optional[str]
69
97
  uniqueIngestionMode: str
98
+ vttConfig: Optional["Content.VttConfig"]
99
+ wordReadMode: Optional[str]
70
100
 
71
101
  class Input(TypedDict):
72
102
  key: str
@@ -76,6 +106,7 @@ class Content(APIResource["Content"]):
76
106
  ownerId: str
77
107
  byteSize: Optional[int]
78
108
  ingestionConfig: "Content.IngestionConfig"
109
+ metadata: dict[str, any] | None = None
79
110
 
80
111
  class UpsertParams(RequestOptions):
81
112
  input: "Content.Input"
@@ -92,6 +123,30 @@ class Content(APIResource["Content"]):
92
123
  endPage: Optional[int]
93
124
  order: Optional[int]
94
125
 
126
+ class ContentInfo(TypedDict):
127
+ """
128
+ Partial representation of the content containing only the base information.
129
+ This is used for the content info endpoint.
130
+ """
131
+
132
+ id: str
133
+ key: str
134
+ url: str | None
135
+ title: str | None
136
+ metadata: Dict[str, Any] | None
137
+ mimeType: str
138
+ byteSize: int
139
+ ownerId: str
140
+ createdAt: str
141
+ updatedAt: str
142
+ expiresAt: str | None
143
+ deletedAt: str | None
144
+ expiredAt: str | None
145
+
146
+ class PaginatedContentInfo(TypedDict):
147
+ contentInfo: List["Content.ContentInfo"]
148
+ totalCount: int
149
+
95
150
  id: str
96
151
  key: str
97
152
  url: Optional[str]
@@ -136,6 +191,42 @@ class Content(APIResource["Content"]):
136
191
  ),
137
192
  )
138
193
 
194
+ @classmethod
195
+ def get_info(
196
+ cls,
197
+ user_id: str,
198
+ company_id: str,
199
+ **params: Unpack["Content.ContentInfoParams"],
200
+ ) -> PaginatedContentInfo:
201
+ return cast(
202
+ Content.PaginatedContentInfo,
203
+ cls._static_request(
204
+ "post",
205
+ "/content/info",
206
+ user_id,
207
+ company_id,
208
+ params=params,
209
+ ),
210
+ )
211
+
212
+ @classmethod
213
+ async def get_info_async(
214
+ cls,
215
+ user_id: str,
216
+ company_id: str,
217
+ **params: Unpack["Content.ContentInfoParams"],
218
+ ) -> PaginatedContentInfo:
219
+ return cast(
220
+ Content.PaginatedContentInfo,
221
+ await cls._static_request_async(
222
+ "post",
223
+ "/content/info",
224
+ user_id,
225
+ company_id,
226
+ params=params,
227
+ ),
228
+ )
229
+
139
230
  @classmethod
140
231
  def upsert(
141
232
  cls,
@@ -8,7 +8,7 @@ class Search(APIResource["Search"]):
8
8
  OBJECT_NAME: ClassVar[Literal["search.search"]] = "search.search"
9
9
 
10
10
  class CreateParams(RequestOptions):
11
- chatId: str
11
+ chatId: NotRequired[Optional[str]]
12
12
  searchString: str
13
13
  searchType: Literal["VECTOR", "COMBINED"]
14
14
  language: NotRequired[Optional[str]]
@@ -1,10 +1,12 @@
1
1
  import os
2
2
  import tempfile
3
3
  from pathlib import Path
4
+ from typing import Optional
4
5
 
5
6
  import requests
6
7
 
7
8
  import unique_sdk
9
+ from unique_sdk.api_resources._content import Content
8
10
 
9
11
 
10
12
  # download readUrl a random directory in /tmp
@@ -38,19 +40,23 @@ def upload_file(
38
40
  mime_type,
39
41
  scope_or_unique_path=None,
40
42
  chat_id=None,
43
+ ingestion_config: Optional[Content.IngestionConfig] = None,
44
+ metadata: dict[str, any] | None = None,
41
45
  ):
42
46
  # check that chatid or scope_or_unique_path is provided
43
47
  if not chat_id and not scope_or_unique_path:
44
48
  raise ValueError("chat_id or scope_or_unique_path must be provided")
45
49
 
46
50
  size = os.path.getsize(path_to_file)
47
- createdContent = unique_sdk.Content.upsert(
51
+ createdContent = Content.upsert(
48
52
  user_id=userId,
49
53
  company_id=companyId,
50
54
  input={
51
55
  "key": displayed_filename,
52
56
  "title": displayed_filename,
53
57
  "mimeType": mime_type,
58
+ "ingestionConfig": ingestion_config,
59
+ "metadata": metadata,
54
60
  },
55
61
  scopeId=scope_or_unique_path,
56
62
  chatId=chat_id,
@@ -78,6 +84,8 @@ def upload_file(
78
84
  "title": displayed_filename,
79
85
  "mimeType": mime_type,
80
86
  "byteSize": size,
87
+ "ingestionConfig": ingestion_config,
88
+ "metadata": metadata,
81
89
  },
82
90
  fileUrl=createdContent.readUrl,
83
91
  chatId=chat_id,
@@ -91,6 +99,8 @@ def upload_file(
91
99
  "title": displayed_filename,
92
100
  "mimeType": mime_type,
93
101
  "byteSize": size,
102
+ "ingestionConfig": ingestion_config,
103
+ "metadata": metadata,
94
104
  },
95
105
  fileUrl=createdContent.readUrl,
96
106
  scopeId=scope_or_unique_path,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_sdk
3
- Version: 0.9.23
3
+ Version: 0.9.28
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: Martin Fadler
@@ -10,6 +10,7 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
13
14
  Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
14
15
  Description-Content-Type: text/markdown
15
16
 
@@ -282,6 +283,73 @@ unique_sdk.Content.search(
282
283
  )
283
284
  ```
284
285
 
286
+ #### `unique_sdk.Content.get_info`
287
+
288
+ Allows you to get content info. To filter the results you can define a metadata filter in UniqueQL language. Find out more about it in the UniqueQL section. An example of a metadata filter defined with UniqueQL is the following:
289
+
290
+ ```python
291
+ metadataFilter: {
292
+ "or": [
293
+ {
294
+ "and": [
295
+ {
296
+ "operator": "contains",
297
+ "path": [
298
+ "folderIdPath"
299
+ ],
300
+ "value": "uniquepathid://test_id"
301
+ },
302
+ {
303
+ "operator": "contains",
304
+ "path": [
305
+ "title"
306
+ ],
307
+ "value": "ai"
308
+ }
309
+ ]
310
+ }
311
+ ]
312
+ },
313
+ ```
314
+
315
+ Pagination is also enabled for this functionality, and the default number of returned results is 50 with no entries skipped. Use the following paramteres to get the desired page:`
316
+
317
+ - `skip`
318
+ - `take`
319
+
320
+ Here is an example of retrieving the first 3 content infos that contain the value `uniquepathid://scope_abcdibgznc4bkdcx120zm5d` in the `folderIdPath` metadata and the value `ai` for the `tile` metadata.
321
+
322
+ ```python
323
+ content_info_result = unique_sdk.Content.get_info(
324
+ user_id=user_id,
325
+ company_id=company_id,
326
+ metadataFilter={
327
+ "or": [
328
+ {
329
+ "and": [
330
+ {
331
+ "operator": "contains",
332
+ "path": [
333
+ "folderIdPath"
334
+ ],
335
+ "value": "uniquepathid://scope_abcdibgznc4bkdcx120zm5d"
336
+ },
337
+ {
338
+ "operator": "contains",
339
+ "path": [
340
+ "title"
341
+ ],
342
+ "value": "ai"
343
+ }
344
+ ]
345
+ }
346
+ ]
347
+ },
348
+ skip=0,
349
+ take=3,
350
+ )
351
+ ```
352
+
285
353
  #### `unique_sdk.Content.upsert`
286
354
 
287
355
  Enables upload of a new Content into the Knowledge base of unique into a specific scope with `scopeId` or a specific `chatId`. One of the two must be set.
@@ -297,6 +365,14 @@ createdContent = upload_file(
297
365
  "test.pdf",
298
366
  "application/pdf",
299
367
  "scope_stcj2osgbl722m22jayidx0n",
368
+ ingestionConfig={
369
+ "chunkMaxTokens": 1000,
370
+ "chunkStrategy": "default",
371
+ "uniqueIngestionMode": "standard",
372
+ },
373
+ metadata={
374
+ "folderIdPath": "uniquepathid://scope_id"
375
+ }
300
376
  )
301
377
 
302
378
  def upload_file(
@@ -306,6 +382,8 @@ def upload_file(
306
382
  displayed_filename,
307
383
  mimeType,
308
384
  scope_or_unique_path,
385
+ ingestion_config=None,
386
+ metadata=None,
309
387
  ):
310
388
  size = os.path.getsize(path_to_file)
311
389
  createdContent = unique_sdk.Content.upsert(
@@ -315,6 +393,8 @@ def upload_file(
315
393
  "key": displayed_filename,
316
394
  "title": displayed_filename,
317
395
  "mimeType": mimeType,
396
+ "ingestionConfig": ingestionConfig,
397
+ "metadata": metadata,
318
398
  },
319
399
  scopeId=scope_or_unique_path,
320
400
  )
@@ -340,6 +420,8 @@ def upload_file(
340
420
  "title": displayed_filename,
341
421
  "mimeType": mimeType,
342
422
  "byteSize": size,
423
+ "ingestionConfig": ingestionConfig,
424
+ "metadata": metadata,
343
425
  },
344
426
  scopeId=scope_or_unique_path,
345
427
  readUrl=createdContent.readUrl,
@@ -544,6 +626,7 @@ These are the options are available for `searchType`:
544
626
  `scopeIds` Specifies a collection of scope IDs to confine the search.
545
627
  `language` Optional. The language specification for full text search.
546
628
  `reranker` Optional. The reranker service to be used for re-ranking the search results.
629
+ `chatId` Optional, adds the documents uploaded in this chat to the scope of searched documents.
547
630
 
548
631
  ```python
549
632
  search = unique_sdk.Search.create(
@@ -715,7 +798,7 @@ A metadata filter such as the one designed above can be used in a `Search.create
715
798
 
716
799
  ### Chat History
717
800
 
718
- #### `unique_sdk.util.chat_history.load_history`
801
+ #### `unique_sdk.utils.chat_history.load_history`
719
802
 
720
803
  A helper function that makes sure the chat history is fully loaded and cut to the size of the token window that it fits into the next round of chat interactions.
721
804
 
@@ -733,7 +816,7 @@ history = unique_sdk.utils.chat_history.load_history(
733
816
  )
734
817
  ```
735
818
 
736
- #### `unique_sdk.util.chat_history.convert_chat_history_to_injectable_string`
819
+ #### `unique_sdk.utils.chat_history.convert_chat_history_to_injectable_string`
737
820
 
738
821
  convert history into a string that can be injected into a prompt. it als returns the token length of the converted history.
739
822
 
@@ -747,7 +830,7 @@ chat_history-string, chat_context_token_length = unique_sdk.utils.chat_history.c
747
830
 
748
831
  Interacting with the knowledge-base.
749
832
 
750
- #### `unique_sdk.util.file_io.download_content`
833
+ #### `unique_sdk.utils.file_io.download_content`
751
834
 
752
835
  download files and save them into a folder in `/tmp`
753
836
 
@@ -763,7 +846,7 @@ pdfFile = download_content(
763
846
  }
764
847
  ```
765
848
 
766
- #### `unique_sdk.util.file_io.upload_file`
849
+ #### `unique_sdk.utils.file_io.upload_file`
767
850
 
768
851
  Allows for uploading files that then get ingested in a scope or a chat.
769
852
 
@@ -773,15 +856,15 @@ createdContent = upload_file(
773
856
  userId=userId,
774
857
  path_to_file="/tmp/hello.pdf",
775
858
  displayed_filename="hello.pdf",
776
- mimeType="application/pdf",
777
- uploadScope="scope_stcj2osgbl722m22jayidx0n",
859
+ mime_type="application/pdf",
860
+ scope_or_unique_path="scope_stcj2osgbl722m22jayidx0n",
778
861
  chat_id=None,
779
862
  )
780
863
  ```
781
864
 
782
865
  ### Sources
783
866
 
784
- #### `unique_sdk.util.sources.merge_sources`
867
+ #### `unique_sdk.utils.sources.merge_sources`
785
868
 
786
869
  Merges multiple search results based on their 'id', removing redundant document and info markers.
787
870
 
@@ -810,15 +893,15 @@ search = unique_sdk.Search.create(
810
893
  chatOnly=False,
811
894
  )
812
895
 
813
- searchContext = unique_sdk.util.token.pick_search_results_for_token_window(
896
+ searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
814
897
  search["data"], config["maxTokens"] - historyLength
815
898
  )
816
899
 
817
- searchContext = unique_sdk.util.sources.merge_sources(search)
900
+ searchContext = unique_sdk.utils.sources.merge_sources(search)
818
901
 
819
902
  ```
820
903
 
821
- #### `unique_sdk.util.sources.sort_sources`
904
+ #### `unique_sdk.utils.sources.sort_sources`
822
905
 
823
906
  Sort sources by order of appearance in documents
824
907
 
@@ -835,14 +918,14 @@ search = unique_sdk.Search.create(
835
918
  chatOnly=False,
836
919
  )
837
920
 
838
- searchContext = unique_sdk.util.token.pick_search_results_for_token_window(
921
+ searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
839
922
  search["data"], config["maxTokens"] - historyLength
840
923
  )
841
924
 
842
- searchContext = unique_sdk.util.sources.sort_sources(search)
925
+ searchContext = unique_sdk.utils.sources.sort_sources(search)
843
926
  ```
844
927
 
845
- #### `unique_sdk.util.sources.post_process_sources`
928
+ #### `unique_sdk.utils.sources.post_process_sources`
846
929
 
847
930
  Post-processes the provided text by converting source references into superscript numerals (required
848
931
  format by backend to display sources in the chat window)
@@ -869,7 +952,7 @@ text_with_sup = post_process_sources(text)
869
952
 
870
953
  ### Token
871
954
 
872
- #### unique_sdk.util.token.pick_search_results_for_token_window
955
+ #### unique_sdk.utils.token.pick_search_results_for_token_window
873
956
 
874
957
  Selects and returns a list of search results that fit within a specified token limit.
875
958
 
@@ -898,12 +981,12 @@ search = unique_sdk.Search.create(
898
981
  chatOnly=False,
899
982
  )
900
983
 
901
- searchContext = unique_sdk.util.token.pick_search_results_for_token_window(
984
+ searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
902
985
  search["data"], config["maxTokens"] - historyLength
903
986
  )
904
987
  ```
905
988
 
906
- #### unique_sdk.util.token.count_tokens
989
+ #### unique_sdk.utils.token.count_tokens
907
990
 
908
991
  Counts the number of tokens in the provided text.
909
992
 
@@ -920,7 +1003,7 @@ Returns:
920
1003
 
921
1004
  ```python
922
1005
  hello = "hello you!"
923
- searchContext = unique_sdk.util.token.count_tokens(hello)
1006
+ searchContext = unique_sdk.utils.token.count_tokens(hello)
924
1007
  ```
925
1008
 
926
1009
  ## Error Handling
@@ -940,6 +1023,20 @@ All notable changes to this project will be documented in this file.
940
1023
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
941
1024
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
942
1025
 
1026
+ ## [0.9.28] - 2025-05-20
1027
+ - Add function to search content info. This also allows filtering content info by metadata info.
1028
+
1029
+ ## [0.9.27] - 2025-05-14
1030
+ - Add the possibility to specify metadata when creating or updating a Content.
1031
+
1032
+ ## [0.9.26] - 2025-05-13
1033
+ - Add the possibility to specify ingestionConfig when creating or updating a Content.
1034
+
1035
+ ## [0.9.25] - 2025-05-02
1036
+ - Fixed typos in `README.md`, including incorrect `sdk.utils` imports and code example errors.
1037
+
1038
+ ## [0.9.24] - 2025-04-23
1039
+ - Make `chatId` property in `Search.CreateParams` optional
943
1040
 
944
1041
  ## [0.9.23] - 2025-03-25
945
1042
  - Define programming language classifier explicitly for python 3.11
@@ -16,20 +16,20 @@ 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
18
  unique_sdk/api_resources/_chat_completion.py,sha256=hAPPHxoljcoHeTboxoJkcXgpqA2hNBu6a6vamdxag58,2000
19
- unique_sdk/api_resources/_content.py,sha256=MrAXhgZS3v2S9OwKh3ROfv5wU8Y947A6gD3wgaYe_aM,4989
19
+ unique_sdk/api_resources/_content.py,sha256=GWCiJMjbiNQFvo8RZ9cnCnTbWMo4NiUxLx-WgTzssc4,7589
20
20
  unique_sdk/api_resources/_embedding.py,sha256=C6qak7cCUBMBINfPhgH8taCJZ9n6w1MUElqDJJ8dG10,1281
21
21
  unique_sdk/api_resources/_event.py,sha256=bpWF9vstdoAWbUzr-iiGP713ceP0zPk77GJXiImf9zg,374
22
22
  unique_sdk/api_resources/_integrated.py,sha256=l1vS8kJiSLie61mqDO3KI2MNmYwFydmCIoJpP_tPhSI,2956
23
23
  unique_sdk/api_resources/_message.py,sha256=gEDIzg3METZU2k7m69meAuf0IWmZxnYOjbBKPRMwPYE,7688
24
24
  unique_sdk/api_resources/_message_assessment.py,sha256=SSfx6eW7zb_GKe8cFJzCqW-t-_eWEXxKP5cnIb0DhIc,2276
25
- unique_sdk/api_resources/_search.py,sha256=m9gL-Cv347r6cM9MwGWgddORGHzPF3jK5dzL3plaeNI,1883
25
+ unique_sdk/api_resources/_search.py,sha256=pAVMXL2AdJNP5JG-7LlaU2Uw1152iUaMZ2YO7fHnNWc,1906
26
26
  unique_sdk/api_resources/_search_string.py,sha256=4Idw6exgZdA8qksz9WkiA68k1hTU-7yFkgT_OLU_GkE,1662
27
27
  unique_sdk/api_resources/_short_term_memory.py,sha256=vPRN-Y0WPx74E6y-A3LocGc0TxJdzT-xGL66WzZwKRg,2820
28
28
  unique_sdk/utils/chat_history.py,sha256=5UqL9hF1O9pV7skbNOlEibF5rHdYsmG3m5-YEPUowOs,3037
29
- unique_sdk/utils/file_io.py,sha256=tcS-5NA97AyiJPhKpWs3i0qKNFsZlttToxrvnWRDJrs,3857
29
+ unique_sdk/utils/file_io.py,sha256=jR1sj1SxOvqmCoLfYkevgTktcTZId0ORoqYjmwVoyJw,4301
30
30
  unique_sdk/utils/sources.py,sha256=wfboE-neMKa0Wuq9QzfAEFMkNLrIrmm0v-QF33sLo6k,4952
31
31
  unique_sdk/utils/token.py,sha256=AzKuAA1AwBtnvSFxGcsHLpxXr_wWE5Mj4jYBbOz2ljA,1740
32
- unique_sdk-0.9.23.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
33
- unique_sdk-0.9.23.dist-info/METADATA,sha256=pL_p-F4itfNfefymBvs0YJv_luucdxZkI3yLprf86Zs,30266
34
- unique_sdk-0.9.23.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
35
- unique_sdk-0.9.23.dist-info/RECORD,,
32
+ unique_sdk-0.9.28.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
33
+ unique_sdk-0.9.28.dist-info/METADATA,sha256=xYS1uF8nf68oCH1Q8veoEejLG5jkDtIuo5NIzy2PDS0,33458
34
+ unique_sdk-0.9.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
35
+ unique_sdk-0.9.28.dist-info/RECORD,,