usecortex-ai 0.3.6__py3-none-any.whl → 0.4.0__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.
Files changed (106) hide show
  1. usecortex_ai/__init__.py +80 -70
  2. usecortex_ai/client.py +25 -23
  3. usecortex_ai/dashboard/client.py +448 -0
  4. usecortex_ai/{user_memory → dashboard}/raw_client.py +371 -530
  5. usecortex_ai/embeddings/client.py +229 -102
  6. usecortex_ai/embeddings/raw_client.py +323 -211
  7. usecortex_ai/errors/__init__.py +2 -0
  8. usecortex_ai/errors/bad_request_error.py +1 -2
  9. usecortex_ai/errors/forbidden_error.py +1 -2
  10. usecortex_ai/errors/internal_server_error.py +1 -2
  11. usecortex_ai/errors/not_found_error.py +1 -2
  12. usecortex_ai/errors/service_unavailable_error.py +1 -2
  13. usecortex_ai/errors/too_many_requests_error.py +11 -0
  14. usecortex_ai/errors/unauthorized_error.py +1 -2
  15. usecortex_ai/fetch/client.py +350 -29
  16. usecortex_ai/fetch/raw_client.py +919 -65
  17. usecortex_ai/raw_client.py +8 -2
  18. usecortex_ai/search/client.py +293 -257
  19. usecortex_ai/search/raw_client.py +445 -346
  20. usecortex_ai/search/types/alpha.py +1 -1
  21. usecortex_ai/sources/client.py +29 -216
  22. usecortex_ai/sources/raw_client.py +51 -589
  23. usecortex_ai/tenant/client.py +155 -118
  24. usecortex_ai/tenant/raw_client.py +227 -350
  25. usecortex_ai/types/__init__.py +74 -66
  26. usecortex_ai/types/add_memory_response.py +39 -0
  27. usecortex_ai/types/{relations.py → api_key_info.py} +25 -5
  28. usecortex_ai/types/app_sources_upload_data.py +15 -6
  29. usecortex_ai/types/{file_upload_result.py → collection_stats.py} +5 -5
  30. usecortex_ai/types/custom_property_definition.py +75 -0
  31. usecortex_ai/types/dashboard_apis_response.py +33 -0
  32. usecortex_ai/types/dashboard_sources_response.py +33 -0
  33. usecortex_ai/types/dashboard_tenants_response.py +33 -0
  34. usecortex_ai/types/{list_sources_response.py → delete_result.py} +10 -7
  35. usecortex_ai/types/delete_user_memory_response.py +1 -1
  36. usecortex_ai/types/entity.py +4 -4
  37. usecortex_ai/types/fetch_mode.py +5 -0
  38. usecortex_ai/types/graph_context.py +26 -0
  39. usecortex_ai/types/{delete_sources.py → infra.py} +4 -3
  40. usecortex_ai/types/{fetch_content_data.py → insert_result.py} +12 -8
  41. usecortex_ai/types/memory_item.py +82 -0
  42. usecortex_ai/types/memory_result_item.py +47 -0
  43. usecortex_ai/types/milvus_data_type.py +21 -0
  44. usecortex_ai/types/path_triplet.py +3 -18
  45. usecortex_ai/types/processing_status.py +3 -2
  46. usecortex_ai/types/processing_status_indexing_status.py +7 -0
  47. usecortex_ai/types/qn_a_search_response.py +49 -0
  48. usecortex_ai/types/{retrieve_response.py → raw_embedding_document.py} +11 -8
  49. usecortex_ai/types/raw_embedding_search_result.py +47 -0
  50. usecortex_ai/types/{user_memory.py → raw_embedding_vector.py} +6 -6
  51. usecortex_ai/types/relation_evidence.py +24 -5
  52. usecortex_ai/types/retrieval_result.py +26 -0
  53. usecortex_ai/types/scored_path_response.py +5 -19
  54. usecortex_ai/types/search_mode.py +5 -0
  55. usecortex_ai/types/{batch_upload_data.py → source_delete_response.py} +8 -8
  56. usecortex_ai/types/{list_user_memories_response.py → source_delete_result_item.py} +11 -7
  57. usecortex_ai/types/source_fetch_response.py +70 -0
  58. usecortex_ai/types/{graph_relations_response.py → source_graph_relations_response.py} +3 -3
  59. usecortex_ai/types/{single_upload_data.py → source_list_response.py} +7 -10
  60. usecortex_ai/types/source_model.py +11 -1
  61. usecortex_ai/types/source_status.py +5 -0
  62. usecortex_ai/types/source_upload_response.py +35 -0
  63. usecortex_ai/types/source_upload_result_item.py +38 -0
  64. usecortex_ai/types/supported_llm_providers.py +5 -0
  65. usecortex_ai/types/{embeddings_create_collection_data.py → tenant_create_response.py} +9 -7
  66. usecortex_ai/types/{webpage_scrape_request.py → tenant_info.py} +10 -5
  67. usecortex_ai/types/{scored_triplet_response.py → tenant_metadata_schema_info.py} +8 -15
  68. usecortex_ai/types/{tenant_create_data.py → tenant_stats_response.py} +9 -8
  69. usecortex_ai/types/{triple_with_evidence.py → triplet_with_evidence.py} +5 -1
  70. usecortex_ai/types/user_assistant_pair.py +4 -0
  71. usecortex_ai/types/{search_chunk.py → vector_store_chunk.py} +3 -14
  72. usecortex_ai/upload/__init__.py +3 -0
  73. usecortex_ai/upload/client.py +233 -1937
  74. usecortex_ai/upload/raw_client.py +364 -4401
  75. usecortex_ai/upload/types/__init__.py +7 -0
  76. usecortex_ai/upload/types/body_upload_app_ingestion_upload_app_post_app_sources.py +7 -0
  77. {usecortex_ai-0.3.6.dist-info → usecortex_ai-0.4.0.dist-info}/METADATA +2 -2
  78. usecortex_ai-0.4.0.dist-info/RECORD +113 -0
  79. {usecortex_ai-0.3.6.dist-info → usecortex_ai-0.4.0.dist-info}/WHEEL +1 -1
  80. usecortex_ai/document/client.py +0 -139
  81. usecortex_ai/document/raw_client.py +0 -312
  82. usecortex_ai/types/add_user_memory_response.py +0 -41
  83. usecortex_ai/types/body_scrape_webpage_upload_scrape_webpage_post.py +0 -17
  84. usecortex_ai/types/body_update_scrape_job_upload_update_webpage_patch.py +0 -17
  85. usecortex_ai/types/chunk_graph_relations_response.py +0 -33
  86. usecortex_ai/types/delete_memory_request.py +0 -32
  87. usecortex_ai/types/delete_sub_tenant_data.py +0 -42
  88. usecortex_ai/types/embeddings_delete_data.py +0 -37
  89. usecortex_ai/types/embeddings_get_data.py +0 -37
  90. usecortex_ai/types/embeddings_search_data.py +0 -37
  91. usecortex_ai/types/extended_context.py +0 -17
  92. usecortex_ai/types/markdown_upload_request.py +0 -41
  93. usecortex_ai/types/related_chunk.py +0 -22
  94. usecortex_ai/types/retrieve_user_memory_response.py +0 -38
  95. usecortex_ai/types/source.py +0 -52
  96. usecortex_ai/types/sub_tenant_ids_data.py +0 -47
  97. usecortex_ai/types/tenant_stats.py +0 -42
  98. usecortex_ai/user/__init__.py +0 -4
  99. usecortex_ai/user/client.py +0 -145
  100. usecortex_ai/user/raw_client.py +0 -316
  101. usecortex_ai/user_memory/__init__.py +0 -4
  102. usecortex_ai/user_memory/client.py +0 -515
  103. usecortex_ai-0.3.6.dist-info/RECORD +0 -112
  104. /usecortex_ai/{document → dashboard}/__init__.py +0 -0
  105. {usecortex_ai-0.3.6.dist-info → usecortex_ai-0.4.0.dist-info}/licenses/LICENSE +0 -0
  106. {usecortex_ai-0.3.6.dist-info → usecortex_ai-0.4.0.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
8
  from ..core.http_response import AsyncHttpResponse, HttpResponse
9
9
  from ..core.pydantic_utilities import parse_obj_as
10
10
  from ..core.request_options import RequestOptions
11
+ from ..core.serialization import convert_and_respect_annotation_metadata
11
12
  from ..errors.bad_request_error import BadRequestError
12
13
  from ..errors.forbidden_error import ForbiddenError
13
14
  from ..errors.internal_server_error import InternalServerError
@@ -15,63 +16,116 @@ from ..errors.not_found_error import NotFoundError
15
16
  from ..errors.service_unavailable_error import ServiceUnavailableError
16
17
  from ..errors.unauthorized_error import UnauthorizedError
17
18
  from ..errors.unprocessable_entity_error import UnprocessableEntityError
18
- from ..types.actual_error_response import ActualErrorResponse
19
- from ..types.delete_sub_tenant_data import DeleteSubTenantData
20
- from ..types.sub_tenant_ids_data import SubTenantIdsData
21
- from ..types.tenant_stats import TenantStats
19
+ from ..types.custom_property_definition import CustomPropertyDefinition
20
+ from ..types.tenant_create_response import TenantCreateResponse
21
+ from ..types.tenant_stats_response import TenantStatsResponse
22
+
23
+ # this is used as the default value for optional parameters
24
+ OMIT = typing.cast(typing.Any, ...)
22
25
 
23
26
 
24
27
  class RawTenantClient:
25
28
  def __init__(self, *, client_wrapper: SyncClientWrapper):
26
29
  self._client_wrapper = client_wrapper
27
30
 
28
- def stats(
31
+ def create_tenant(
29
32
  self,
30
33
  *,
31
34
  tenant_id: str,
32
- sub_tenant_id: typing.Optional[str] = None,
35
+ is_embeddings_tenant: typing.Optional[bool] = OMIT,
36
+ embeddings_dimension: typing.Optional[int] = OMIT,
37
+ tenant_metadata_schema: typing.Optional[typing.Sequence[CustomPropertyDefinition]] = OMIT,
33
38
  request_options: typing.Optional[RequestOptions] = None,
34
- ) -> HttpResponse[TenantStats]:
39
+ ) -> HttpResponse[TenantCreateResponse]:
35
40
  """
36
- Retrieve usage stats for your tenant.
37
-
38
- Use this endpoint to check whether a tenant exists and view core metrics like total indexed objects and vector dimension. This helps you validate setup and monitor ingestion.
39
-
40
- Expected outcome
41
- - You receive the current object count and vector dimension for the tenant.
42
- - If the tenant does not exist, you get a not-found error.
41
+ Create a tenant for your account.
42
+
43
+ Use this endpoint to initialize a tenant space you can use for ingestion, embeddings, and search.
44
+
45
+ **Tenant Metadata Schema**
46
+
47
+ You can optionally provide a `tenant_metadata_schema` to define custom fields that will be
48
+ indexed in the vector store. Each field can be configured with:
49
+
50
+ - `enable_match`: Enable text filtering on this field
51
+ - `enable_dense_embedding`: Create dense embeddings for semantic similarity search
52
+ - `enable_sparse_embedding`: Create sparse embeddings (BM25) for keyword search
53
+
54
+ **Example Request:**
55
+ ```json
56
+ {
57
+ "tenant_id": "my-tenant",
58
+ "tenant_metadata_schema": [
59
+ {
60
+ "name": "category",
61
+ "data_type": "VARCHAR",
62
+ "max_length": 256,
63
+ "enable_match": true
64
+ },
65
+ {
66
+ "name": "product_description",
67
+ "data_type": "VARCHAR",
68
+ "max_length": 4096,
69
+ "enable_dense_embedding": true,
70
+ "enable_sparse_embedding": true
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+
76
+ Expected outcome:
77
+ - A tenant is created and returned with its identifier.
78
+ - If tenant_metadata_schema is provided, the vector store collection will include
79
+ the specified custom fields with their configured search capabilities.
80
+ - If the tenant already exists, you receive a success message with the existing identifier.
43
81
 
44
82
  Parameters
45
83
  ----------
46
84
  tenant_id : str
47
- Unique identifier for the tenant/organization
85
+ Unique tenant identifier
86
+
87
+ is_embeddings_tenant : typing.Optional[bool]
88
+ True to create embeddings tenant
89
+
90
+ embeddings_dimension : typing.Optional[int]
91
+ Embedding dimensions for embeddings tenant. Not required for non-embeddings (is_embeddings_tenant=False) tenants
48
92
 
49
- sub_tenant_id : typing.Optional[str]
50
- Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
93
+ tenant_metadata_schema : typing.Optional[typing.Sequence[CustomPropertyDefinition]]
94
+ Schema definition for tenant metadata fields. Each field can be configured for: filtering (enable_match), semantic search (enable_dense_embedding), and/or keyword search (enable_sparse_embedding). Fields with embeddings enabled must be VARCHAR type.
51
95
 
52
96
  request_options : typing.Optional[RequestOptions]
53
97
  Request-specific configuration.
54
98
 
55
99
  Returns
56
100
  -------
57
- HttpResponse[TenantStats]
101
+ HttpResponse[TenantCreateResponse]
58
102
  Successful Response
59
103
  """
60
104
  _response = self._client_wrapper.httpx_client.request(
61
- "tenant/stats",
62
- method="GET",
63
- params={
105
+ "tenants/create",
106
+ method="POST",
107
+ json={
64
108
  "tenant_id": tenant_id,
65
- "sub_tenant_id": sub_tenant_id,
109
+ "is_embeddings_tenant": is_embeddings_tenant,
110
+ "embeddings_dimension": embeddings_dimension,
111
+ "tenant_metadata_schema": convert_and_respect_annotation_metadata(
112
+ object_=tenant_metadata_schema,
113
+ annotation=typing.Sequence[CustomPropertyDefinition],
114
+ direction="write",
115
+ ),
116
+ },
117
+ headers={
118
+ "content-type": "application/json",
66
119
  },
67
120
  request_options=request_options,
121
+ omit=OMIT,
68
122
  )
69
123
  try:
70
124
  if 200 <= _response.status_code < 300:
71
125
  _data = typing.cast(
72
- TenantStats,
126
+ TenantCreateResponse,
73
127
  parse_obj_as(
74
- type_=TenantStats, # type: ignore
128
+ type_=TenantCreateResponse, # type: ignore
75
129
  object_=_response.json(),
76
130
  ),
77
131
  )
@@ -80,9 +134,9 @@ class RawTenantClient:
80
134
  raise BadRequestError(
81
135
  headers=dict(_response.headers),
82
136
  body=typing.cast(
83
- ActualErrorResponse,
137
+ typing.Optional[typing.Any],
84
138
  parse_obj_as(
85
- type_=ActualErrorResponse, # type: ignore
139
+ type_=typing.Optional[typing.Any], # type: ignore
86
140
  object_=_response.json(),
87
141
  ),
88
142
  ),
@@ -91,9 +145,9 @@ class RawTenantClient:
91
145
  raise UnauthorizedError(
92
146
  headers=dict(_response.headers),
93
147
  body=typing.cast(
94
- ActualErrorResponse,
148
+ typing.Optional[typing.Any],
95
149
  parse_obj_as(
96
- type_=ActualErrorResponse, # type: ignore
150
+ type_=typing.Optional[typing.Any], # type: ignore
97
151
  object_=_response.json(),
98
152
  ),
99
153
  ),
@@ -102,9 +156,9 @@ class RawTenantClient:
102
156
  raise ForbiddenError(
103
157
  headers=dict(_response.headers),
104
158
  body=typing.cast(
105
- ActualErrorResponse,
159
+ typing.Optional[typing.Any],
106
160
  parse_obj_as(
107
- type_=ActualErrorResponse, # type: ignore
161
+ type_=typing.Optional[typing.Any], # type: ignore
108
162
  object_=_response.json(),
109
163
  ),
110
164
  ),
@@ -113,9 +167,9 @@ class RawTenantClient:
113
167
  raise NotFoundError(
114
168
  headers=dict(_response.headers),
115
169
  body=typing.cast(
116
- ActualErrorResponse,
170
+ typing.Optional[typing.Any],
117
171
  parse_obj_as(
118
- type_=ActualErrorResponse, # type: ignore
172
+ type_=typing.Optional[typing.Any], # type: ignore
119
173
  object_=_response.json(),
120
174
  ),
121
175
  ),
@@ -135,9 +189,9 @@ class RawTenantClient:
135
189
  raise InternalServerError(
136
190
  headers=dict(_response.headers),
137
191
  body=typing.cast(
138
- ActualErrorResponse,
192
+ typing.Optional[typing.Any],
139
193
  parse_obj_as(
140
- type_=ActualErrorResponse, # type: ignore
194
+ type_=typing.Optional[typing.Any], # type: ignore
141
195
  object_=_response.json(),
142
196
  ),
143
197
  ),
@@ -146,9 +200,9 @@ class RawTenantClient:
146
200
  raise ServiceUnavailableError(
147
201
  headers=dict(_response.headers),
148
202
  body=typing.cast(
149
- ActualErrorResponse,
203
+ typing.Optional[typing.Any],
150
204
  parse_obj_as(
151
- type_=ActualErrorResponse, # type: ignore
205
+ type_=typing.Optional[typing.Any], # type: ignore
152
206
  object_=_response.json(),
153
207
  ),
154
208
  ),
@@ -158,162 +212,48 @@ class RawTenantClient:
158
212
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
159
213
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
160
214
 
161
- def get_sub_tenant_ids(
215
+ def stats(
162
216
  self, *, tenant_id: str, request_options: typing.Optional[RequestOptions] = None
163
- ) -> HttpResponse[SubTenantIdsData]:
217
+ ) -> HttpResponse[TenantStatsResponse]:
164
218
  """
165
- Retrieve all sub-tenant IDs contained within a specific tenant. Fetches the sub-tenant IDs directly from the underlying data store.
166
-
167
- Parameters
168
- ----------
169
- tenant_id : str
170
-
171
- request_options : typing.Optional[RequestOptions]
172
- Request-specific configuration.
219
+ Retrieve usage stats for your tenant.
173
220
 
174
- Returns
175
- -------
176
- HttpResponse[SubTenantIdsData]
177
- Successful Response
178
- """
179
- _response = self._client_wrapper.httpx_client.request(
180
- "tenant/sub_tenant_ids",
181
- method="GET",
182
- params={
183
- "tenant_id": tenant_id,
184
- },
185
- request_options=request_options,
186
- )
187
- try:
188
- if 200 <= _response.status_code < 300:
189
- _data = typing.cast(
190
- SubTenantIdsData,
191
- parse_obj_as(
192
- type_=SubTenantIdsData, # type: ignore
193
- object_=_response.json(),
194
- ),
195
- )
196
- return HttpResponse(response=_response, data=_data)
197
- if _response.status_code == 400:
198
- raise BadRequestError(
199
- headers=dict(_response.headers),
200
- body=typing.cast(
201
- ActualErrorResponse,
202
- parse_obj_as(
203
- type_=ActualErrorResponse, # type: ignore
204
- object_=_response.json(),
205
- ),
206
- ),
207
- )
208
- if _response.status_code == 401:
209
- raise UnauthorizedError(
210
- headers=dict(_response.headers),
211
- body=typing.cast(
212
- ActualErrorResponse,
213
- parse_obj_as(
214
- type_=ActualErrorResponse, # type: ignore
215
- object_=_response.json(),
216
- ),
217
- ),
218
- )
219
- if _response.status_code == 403:
220
- raise ForbiddenError(
221
- headers=dict(_response.headers),
222
- body=typing.cast(
223
- ActualErrorResponse,
224
- parse_obj_as(
225
- type_=ActualErrorResponse, # type: ignore
226
- object_=_response.json(),
227
- ),
228
- ),
229
- )
230
- if _response.status_code == 404:
231
- raise NotFoundError(
232
- headers=dict(_response.headers),
233
- body=typing.cast(
234
- ActualErrorResponse,
235
- parse_obj_as(
236
- type_=ActualErrorResponse, # type: ignore
237
- object_=_response.json(),
238
- ),
239
- ),
240
- )
241
- if _response.status_code == 422:
242
- raise UnprocessableEntityError(
243
- headers=dict(_response.headers),
244
- body=typing.cast(
245
- typing.Optional[typing.Any],
246
- parse_obj_as(
247
- type_=typing.Optional[typing.Any], # type: ignore
248
- object_=_response.json(),
249
- ),
250
- ),
251
- )
252
- if _response.status_code == 500:
253
- raise InternalServerError(
254
- headers=dict(_response.headers),
255
- body=typing.cast(
256
- ActualErrorResponse,
257
- parse_obj_as(
258
- type_=ActualErrorResponse, # type: ignore
259
- object_=_response.json(),
260
- ),
261
- ),
262
- )
263
- if _response.status_code == 503:
264
- raise ServiceUnavailableError(
265
- headers=dict(_response.headers),
266
- body=typing.cast(
267
- ActualErrorResponse,
268
- parse_obj_as(
269
- type_=ActualErrorResponse, # type: ignore
270
- object_=_response.json(),
271
- ),
272
- ),
273
- )
274
- _response_json = _response.json()
275
- except JSONDecodeError:
276
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
277
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
221
+ Use this endpoint to check whether a tenant exists and view core metrics like total
222
+ indexed objects and vector dimension. This helps you validate
223
+ setup and monitor ingestion.
278
224
 
279
- def delete_sub_tenant(
280
- self, *, tenant_id: str, sub_tenant_id: str, request_options: typing.Optional[RequestOptions] = None
281
- ) -> HttpResponse[DeleteSubTenantData]:
282
- """
283
- Delete a sub-tenant from a given tenant.
225
+ Expected outcome
284
226
 
285
- This endpoint deletes a specific sub-tenant from the specified tenant.
286
- It validates that the sub-tenant is not the primary/default sub-tenant before deletion.
227
+ You receive the current object count and vector dimension for the tenant.
228
+ If the tenant does not exist, you get a not-found error.
287
229
 
288
230
  Parameters
289
231
  ----------
290
232
  tenant_id : str
291
-
292
- sub_tenant_id : str
233
+ Unique identifier for the tenant/organization
293
234
 
294
235
  request_options : typing.Optional[RequestOptions]
295
236
  Request-specific configuration.
296
237
 
297
238
  Returns
298
239
  -------
299
- HttpResponse[DeleteSubTenantData]
240
+ HttpResponse[TenantStatsResponse]
300
241
  Successful Response
301
242
  """
302
243
  _response = self._client_wrapper.httpx_client.request(
303
- "tenant/delete_sub_tenant",
304
- method="DELETE",
244
+ "tenants/stats",
245
+ method="GET",
305
246
  params={
306
247
  "tenant_id": tenant_id,
307
- "sub_tenant_id": sub_tenant_id,
308
248
  },
309
249
  request_options=request_options,
310
250
  )
311
251
  try:
312
252
  if 200 <= _response.status_code < 300:
313
253
  _data = typing.cast(
314
- DeleteSubTenantData,
254
+ TenantStatsResponse,
315
255
  parse_obj_as(
316
- type_=DeleteSubTenantData, # type: ignore
256
+ type_=TenantStatsResponse, # type: ignore
317
257
  object_=_response.json(),
318
258
  ),
319
259
  )
@@ -322,9 +262,9 @@ class RawTenantClient:
322
262
  raise BadRequestError(
323
263
  headers=dict(_response.headers),
324
264
  body=typing.cast(
325
- ActualErrorResponse,
265
+ typing.Optional[typing.Any],
326
266
  parse_obj_as(
327
- type_=ActualErrorResponse, # type: ignore
267
+ type_=typing.Optional[typing.Any], # type: ignore
328
268
  object_=_response.json(),
329
269
  ),
330
270
  ),
@@ -333,9 +273,9 @@ class RawTenantClient:
333
273
  raise UnauthorizedError(
334
274
  headers=dict(_response.headers),
335
275
  body=typing.cast(
336
- ActualErrorResponse,
276
+ typing.Optional[typing.Any],
337
277
  parse_obj_as(
338
- type_=ActualErrorResponse, # type: ignore
278
+ type_=typing.Optional[typing.Any], # type: ignore
339
279
  object_=_response.json(),
340
280
  ),
341
281
  ),
@@ -344,9 +284,9 @@ class RawTenantClient:
344
284
  raise ForbiddenError(
345
285
  headers=dict(_response.headers),
346
286
  body=typing.cast(
347
- ActualErrorResponse,
287
+ typing.Optional[typing.Any],
348
288
  parse_obj_as(
349
- type_=ActualErrorResponse, # type: ignore
289
+ type_=typing.Optional[typing.Any], # type: ignore
350
290
  object_=_response.json(),
351
291
  ),
352
292
  ),
@@ -355,9 +295,9 @@ class RawTenantClient:
355
295
  raise NotFoundError(
356
296
  headers=dict(_response.headers),
357
297
  body=typing.cast(
358
- ActualErrorResponse,
298
+ typing.Optional[typing.Any],
359
299
  parse_obj_as(
360
- type_=ActualErrorResponse, # type: ignore
300
+ type_=typing.Optional[typing.Any], # type: ignore
361
301
  object_=_response.json(),
362
302
  ),
363
303
  ),
@@ -377,9 +317,9 @@ class RawTenantClient:
377
317
  raise InternalServerError(
378
318
  headers=dict(_response.headers),
379
319
  body=typing.cast(
380
- ActualErrorResponse,
320
+ typing.Optional[typing.Any],
381
321
  parse_obj_as(
382
- type_=ActualErrorResponse, # type: ignore
322
+ type_=typing.Optional[typing.Any], # type: ignore
383
323
  object_=_response.json(),
384
324
  ),
385
325
  ),
@@ -388,9 +328,9 @@ class RawTenantClient:
388
328
  raise ServiceUnavailableError(
389
329
  headers=dict(_response.headers),
390
330
  body=typing.cast(
391
- ActualErrorResponse,
331
+ typing.Optional[typing.Any],
392
332
  parse_obj_as(
393
- type_=ActualErrorResponse, # type: ignore
333
+ type_=typing.Optional[typing.Any], # type: ignore
394
334
  object_=_response.json(),
395
335
  ),
396
336
  ),
@@ -405,53 +345,104 @@ class AsyncRawTenantClient:
405
345
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
406
346
  self._client_wrapper = client_wrapper
407
347
 
408
- async def stats(
348
+ async def create_tenant(
409
349
  self,
410
350
  *,
411
351
  tenant_id: str,
412
- sub_tenant_id: typing.Optional[str] = None,
352
+ is_embeddings_tenant: typing.Optional[bool] = OMIT,
353
+ embeddings_dimension: typing.Optional[int] = OMIT,
354
+ tenant_metadata_schema: typing.Optional[typing.Sequence[CustomPropertyDefinition]] = OMIT,
413
355
  request_options: typing.Optional[RequestOptions] = None,
414
- ) -> AsyncHttpResponse[TenantStats]:
356
+ ) -> AsyncHttpResponse[TenantCreateResponse]:
415
357
  """
416
- Retrieve usage stats for your tenant.
417
-
418
- Use this endpoint to check whether a tenant exists and view core metrics like total indexed objects and vector dimension. This helps you validate setup and monitor ingestion.
419
-
420
- Expected outcome
421
- - You receive the current object count and vector dimension for the tenant.
422
- - If the tenant does not exist, you get a not-found error.
358
+ Create a tenant for your account.
359
+
360
+ Use this endpoint to initialize a tenant space you can use for ingestion, embeddings, and search.
361
+
362
+ **Tenant Metadata Schema**
363
+
364
+ You can optionally provide a `tenant_metadata_schema` to define custom fields that will be
365
+ indexed in the vector store. Each field can be configured with:
366
+
367
+ - `enable_match`: Enable text filtering on this field
368
+ - `enable_dense_embedding`: Create dense embeddings for semantic similarity search
369
+ - `enable_sparse_embedding`: Create sparse embeddings (BM25) for keyword search
370
+
371
+ **Example Request:**
372
+ ```json
373
+ {
374
+ "tenant_id": "my-tenant",
375
+ "tenant_metadata_schema": [
376
+ {
377
+ "name": "category",
378
+ "data_type": "VARCHAR",
379
+ "max_length": 256,
380
+ "enable_match": true
381
+ },
382
+ {
383
+ "name": "product_description",
384
+ "data_type": "VARCHAR",
385
+ "max_length": 4096,
386
+ "enable_dense_embedding": true,
387
+ "enable_sparse_embedding": true
388
+ }
389
+ ]
390
+ }
391
+ ```
392
+
393
+ Expected outcome:
394
+ - A tenant is created and returned with its identifier.
395
+ - If tenant_metadata_schema is provided, the vector store collection will include
396
+ the specified custom fields with their configured search capabilities.
397
+ - If the tenant already exists, you receive a success message with the existing identifier.
423
398
 
424
399
  Parameters
425
400
  ----------
426
401
  tenant_id : str
427
- Unique identifier for the tenant/organization
402
+ Unique tenant identifier
403
+
404
+ is_embeddings_tenant : typing.Optional[bool]
405
+ True to create embeddings tenant
428
406
 
429
- sub_tenant_id : typing.Optional[str]
430
- Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
407
+ embeddings_dimension : typing.Optional[int]
408
+ Embedding dimensions for embeddings tenant. Not required for non-embeddings (is_embeddings_tenant=False) tenants
409
+
410
+ tenant_metadata_schema : typing.Optional[typing.Sequence[CustomPropertyDefinition]]
411
+ Schema definition for tenant metadata fields. Each field can be configured for: filtering (enable_match), semantic search (enable_dense_embedding), and/or keyword search (enable_sparse_embedding). Fields with embeddings enabled must be VARCHAR type.
431
412
 
432
413
  request_options : typing.Optional[RequestOptions]
433
414
  Request-specific configuration.
434
415
 
435
416
  Returns
436
417
  -------
437
- AsyncHttpResponse[TenantStats]
418
+ AsyncHttpResponse[TenantCreateResponse]
438
419
  Successful Response
439
420
  """
440
421
  _response = await self._client_wrapper.httpx_client.request(
441
- "tenant/stats",
442
- method="GET",
443
- params={
422
+ "tenants/create",
423
+ method="POST",
424
+ json={
444
425
  "tenant_id": tenant_id,
445
- "sub_tenant_id": sub_tenant_id,
426
+ "is_embeddings_tenant": is_embeddings_tenant,
427
+ "embeddings_dimension": embeddings_dimension,
428
+ "tenant_metadata_schema": convert_and_respect_annotation_metadata(
429
+ object_=tenant_metadata_schema,
430
+ annotation=typing.Sequence[CustomPropertyDefinition],
431
+ direction="write",
432
+ ),
433
+ },
434
+ headers={
435
+ "content-type": "application/json",
446
436
  },
447
437
  request_options=request_options,
438
+ omit=OMIT,
448
439
  )
449
440
  try:
450
441
  if 200 <= _response.status_code < 300:
451
442
  _data = typing.cast(
452
- TenantStats,
443
+ TenantCreateResponse,
453
444
  parse_obj_as(
454
- type_=TenantStats, # type: ignore
445
+ type_=TenantCreateResponse, # type: ignore
455
446
  object_=_response.json(),
456
447
  ),
457
448
  )
@@ -460,9 +451,9 @@ class AsyncRawTenantClient:
460
451
  raise BadRequestError(
461
452
  headers=dict(_response.headers),
462
453
  body=typing.cast(
463
- ActualErrorResponse,
454
+ typing.Optional[typing.Any],
464
455
  parse_obj_as(
465
- type_=ActualErrorResponse, # type: ignore
456
+ type_=typing.Optional[typing.Any], # type: ignore
466
457
  object_=_response.json(),
467
458
  ),
468
459
  ),
@@ -471,9 +462,9 @@ class AsyncRawTenantClient:
471
462
  raise UnauthorizedError(
472
463
  headers=dict(_response.headers),
473
464
  body=typing.cast(
474
- ActualErrorResponse,
465
+ typing.Optional[typing.Any],
475
466
  parse_obj_as(
476
- type_=ActualErrorResponse, # type: ignore
467
+ type_=typing.Optional[typing.Any], # type: ignore
477
468
  object_=_response.json(),
478
469
  ),
479
470
  ),
@@ -482,9 +473,9 @@ class AsyncRawTenantClient:
482
473
  raise ForbiddenError(
483
474
  headers=dict(_response.headers),
484
475
  body=typing.cast(
485
- ActualErrorResponse,
476
+ typing.Optional[typing.Any],
486
477
  parse_obj_as(
487
- type_=ActualErrorResponse, # type: ignore
478
+ type_=typing.Optional[typing.Any], # type: ignore
488
479
  object_=_response.json(),
489
480
  ),
490
481
  ),
@@ -493,9 +484,9 @@ class AsyncRawTenantClient:
493
484
  raise NotFoundError(
494
485
  headers=dict(_response.headers),
495
486
  body=typing.cast(
496
- ActualErrorResponse,
487
+ typing.Optional[typing.Any],
497
488
  parse_obj_as(
498
- type_=ActualErrorResponse, # type: ignore
489
+ type_=typing.Optional[typing.Any], # type: ignore
499
490
  object_=_response.json(),
500
491
  ),
501
492
  ),
@@ -515,9 +506,9 @@ class AsyncRawTenantClient:
515
506
  raise InternalServerError(
516
507
  headers=dict(_response.headers),
517
508
  body=typing.cast(
518
- ActualErrorResponse,
509
+ typing.Optional[typing.Any],
519
510
  parse_obj_as(
520
- type_=ActualErrorResponse, # type: ignore
511
+ type_=typing.Optional[typing.Any], # type: ignore
521
512
  object_=_response.json(),
522
513
  ),
523
514
  ),
@@ -526,9 +517,9 @@ class AsyncRawTenantClient:
526
517
  raise ServiceUnavailableError(
527
518
  headers=dict(_response.headers),
528
519
  body=typing.cast(
529
- ActualErrorResponse,
520
+ typing.Optional[typing.Any],
530
521
  parse_obj_as(
531
- type_=ActualErrorResponse, # type: ignore
522
+ type_=typing.Optional[typing.Any], # type: ignore
532
523
  object_=_response.json(),
533
524
  ),
534
525
  ),
@@ -538,162 +529,48 @@ class AsyncRawTenantClient:
538
529
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
539
530
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
540
531
 
541
- async def get_sub_tenant_ids(
532
+ async def stats(
542
533
  self, *, tenant_id: str, request_options: typing.Optional[RequestOptions] = None
543
- ) -> AsyncHttpResponse[SubTenantIdsData]:
534
+ ) -> AsyncHttpResponse[TenantStatsResponse]:
544
535
  """
545
- Retrieve all sub-tenant IDs contained within a specific tenant. Fetches the sub-tenant IDs directly from the underlying data store.
546
-
547
- Parameters
548
- ----------
549
- tenant_id : str
536
+ Retrieve usage stats for your tenant.
550
537
 
551
- request_options : typing.Optional[RequestOptions]
552
- Request-specific configuration.
538
+ Use this endpoint to check whether a tenant exists and view core metrics like total
539
+ indexed objects and vector dimension. This helps you validate
540
+ setup and monitor ingestion.
553
541
 
554
- Returns
555
- -------
556
- AsyncHttpResponse[SubTenantIdsData]
557
- Successful Response
558
- """
559
- _response = await self._client_wrapper.httpx_client.request(
560
- "tenant/sub_tenant_ids",
561
- method="GET",
562
- params={
563
- "tenant_id": tenant_id,
564
- },
565
- request_options=request_options,
566
- )
567
- try:
568
- if 200 <= _response.status_code < 300:
569
- _data = typing.cast(
570
- SubTenantIdsData,
571
- parse_obj_as(
572
- type_=SubTenantIdsData, # type: ignore
573
- object_=_response.json(),
574
- ),
575
- )
576
- return AsyncHttpResponse(response=_response, data=_data)
577
- if _response.status_code == 400:
578
- raise BadRequestError(
579
- headers=dict(_response.headers),
580
- body=typing.cast(
581
- ActualErrorResponse,
582
- parse_obj_as(
583
- type_=ActualErrorResponse, # type: ignore
584
- object_=_response.json(),
585
- ),
586
- ),
587
- )
588
- if _response.status_code == 401:
589
- raise UnauthorizedError(
590
- headers=dict(_response.headers),
591
- body=typing.cast(
592
- ActualErrorResponse,
593
- parse_obj_as(
594
- type_=ActualErrorResponse, # type: ignore
595
- object_=_response.json(),
596
- ),
597
- ),
598
- )
599
- if _response.status_code == 403:
600
- raise ForbiddenError(
601
- headers=dict(_response.headers),
602
- body=typing.cast(
603
- ActualErrorResponse,
604
- parse_obj_as(
605
- type_=ActualErrorResponse, # type: ignore
606
- object_=_response.json(),
607
- ),
608
- ),
609
- )
610
- if _response.status_code == 404:
611
- raise NotFoundError(
612
- headers=dict(_response.headers),
613
- body=typing.cast(
614
- ActualErrorResponse,
615
- parse_obj_as(
616
- type_=ActualErrorResponse, # type: ignore
617
- object_=_response.json(),
618
- ),
619
- ),
620
- )
621
- if _response.status_code == 422:
622
- raise UnprocessableEntityError(
623
- headers=dict(_response.headers),
624
- body=typing.cast(
625
- typing.Optional[typing.Any],
626
- parse_obj_as(
627
- type_=typing.Optional[typing.Any], # type: ignore
628
- object_=_response.json(),
629
- ),
630
- ),
631
- )
632
- if _response.status_code == 500:
633
- raise InternalServerError(
634
- headers=dict(_response.headers),
635
- body=typing.cast(
636
- ActualErrorResponse,
637
- parse_obj_as(
638
- type_=ActualErrorResponse, # type: ignore
639
- object_=_response.json(),
640
- ),
641
- ),
642
- )
643
- if _response.status_code == 503:
644
- raise ServiceUnavailableError(
645
- headers=dict(_response.headers),
646
- body=typing.cast(
647
- ActualErrorResponse,
648
- parse_obj_as(
649
- type_=ActualErrorResponse, # type: ignore
650
- object_=_response.json(),
651
- ),
652
- ),
653
- )
654
- _response_json = _response.json()
655
- except JSONDecodeError:
656
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
657
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
658
-
659
- async def delete_sub_tenant(
660
- self, *, tenant_id: str, sub_tenant_id: str, request_options: typing.Optional[RequestOptions] = None
661
- ) -> AsyncHttpResponse[DeleteSubTenantData]:
662
- """
663
- Delete a sub-tenant from a given tenant.
542
+ Expected outcome
664
543
 
665
- This endpoint deletes a specific sub-tenant from the specified tenant.
666
- It validates that the sub-tenant is not the primary/default sub-tenant before deletion.
544
+ You receive the current object count and vector dimension for the tenant.
545
+ If the tenant does not exist, you get a not-found error.
667
546
 
668
547
  Parameters
669
548
  ----------
670
549
  tenant_id : str
671
-
672
- sub_tenant_id : str
550
+ Unique identifier for the tenant/organization
673
551
 
674
552
  request_options : typing.Optional[RequestOptions]
675
553
  Request-specific configuration.
676
554
 
677
555
  Returns
678
556
  -------
679
- AsyncHttpResponse[DeleteSubTenantData]
557
+ AsyncHttpResponse[TenantStatsResponse]
680
558
  Successful Response
681
559
  """
682
560
  _response = await self._client_wrapper.httpx_client.request(
683
- "tenant/delete_sub_tenant",
684
- method="DELETE",
561
+ "tenants/stats",
562
+ method="GET",
685
563
  params={
686
564
  "tenant_id": tenant_id,
687
- "sub_tenant_id": sub_tenant_id,
688
565
  },
689
566
  request_options=request_options,
690
567
  )
691
568
  try:
692
569
  if 200 <= _response.status_code < 300:
693
570
  _data = typing.cast(
694
- DeleteSubTenantData,
571
+ TenantStatsResponse,
695
572
  parse_obj_as(
696
- type_=DeleteSubTenantData, # type: ignore
573
+ type_=TenantStatsResponse, # type: ignore
697
574
  object_=_response.json(),
698
575
  ),
699
576
  )
@@ -702,9 +579,9 @@ class AsyncRawTenantClient:
702
579
  raise BadRequestError(
703
580
  headers=dict(_response.headers),
704
581
  body=typing.cast(
705
- ActualErrorResponse,
582
+ typing.Optional[typing.Any],
706
583
  parse_obj_as(
707
- type_=ActualErrorResponse, # type: ignore
584
+ type_=typing.Optional[typing.Any], # type: ignore
708
585
  object_=_response.json(),
709
586
  ),
710
587
  ),
@@ -713,9 +590,9 @@ class AsyncRawTenantClient:
713
590
  raise UnauthorizedError(
714
591
  headers=dict(_response.headers),
715
592
  body=typing.cast(
716
- ActualErrorResponse,
593
+ typing.Optional[typing.Any],
717
594
  parse_obj_as(
718
- type_=ActualErrorResponse, # type: ignore
595
+ type_=typing.Optional[typing.Any], # type: ignore
719
596
  object_=_response.json(),
720
597
  ),
721
598
  ),
@@ -724,9 +601,9 @@ class AsyncRawTenantClient:
724
601
  raise ForbiddenError(
725
602
  headers=dict(_response.headers),
726
603
  body=typing.cast(
727
- ActualErrorResponse,
604
+ typing.Optional[typing.Any],
728
605
  parse_obj_as(
729
- type_=ActualErrorResponse, # type: ignore
606
+ type_=typing.Optional[typing.Any], # type: ignore
730
607
  object_=_response.json(),
731
608
  ),
732
609
  ),
@@ -735,9 +612,9 @@ class AsyncRawTenantClient:
735
612
  raise NotFoundError(
736
613
  headers=dict(_response.headers),
737
614
  body=typing.cast(
738
- ActualErrorResponse,
615
+ typing.Optional[typing.Any],
739
616
  parse_obj_as(
740
- type_=ActualErrorResponse, # type: ignore
617
+ type_=typing.Optional[typing.Any], # type: ignore
741
618
  object_=_response.json(),
742
619
  ),
743
620
  ),
@@ -757,9 +634,9 @@ class AsyncRawTenantClient:
757
634
  raise InternalServerError(
758
635
  headers=dict(_response.headers),
759
636
  body=typing.cast(
760
- ActualErrorResponse,
637
+ typing.Optional[typing.Any],
761
638
  parse_obj_as(
762
- type_=ActualErrorResponse, # type: ignore
639
+ type_=typing.Optional[typing.Any], # type: ignore
763
640
  object_=_response.json(),
764
641
  ),
765
642
  ),
@@ -768,9 +645,9 @@ class AsyncRawTenantClient:
768
645
  raise ServiceUnavailableError(
769
646
  headers=dict(_response.headers),
770
647
  body=typing.cast(
771
- ActualErrorResponse,
648
+ typing.Optional[typing.Any],
772
649
  parse_obj_as(
773
- type_=ActualErrorResponse, # type: ignore
650
+ type_=typing.Optional[typing.Any], # type: ignore
774
651
  object_=_response.json(),
775
652
  ),
776
653
  ),