usecortex-ai 0.3.4__py3-none-any.whl → 0.3.5__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.
@@ -20,9 +20,11 @@ from ..errors.unprocessable_entity_error import UnprocessableEntityError
20
20
  from ..types.actual_error_response import ActualErrorResponse
21
21
  from ..types.app_sources_upload_data import AppSourcesUploadData
22
22
  from ..types.batch_upload_data import BatchUploadData
23
+ from ..types.markdown_upload_request import MarkdownUploadRequest
23
24
  from ..types.processing_status import ProcessingStatus
24
25
  from ..types.single_upload_data import SingleUploadData
25
26
  from ..types.source_model import SourceModel
27
+ from ..types.webpage_scrape_request import WebpageScrapeRequest
26
28
 
27
29
  # this is used as the default value for optional parameters
28
30
  OMIT = typing.cast(typing.Any, ...)
@@ -1487,55 +1489,47 @@ class RawUploadClient:
1487
1489
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1488
1490
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1489
1491
 
1490
- def upload_embeddings(
1492
+ def batch_upload_markdown(
1491
1493
  self,
1492
1494
  *,
1493
1495
  tenant_id: str,
1494
- embeddings: typing.Sequence[typing.Sequence[float]],
1496
+ request: typing.Sequence[MarkdownUploadRequest],
1495
1497
  sub_tenant_id: typing.Optional[str] = None,
1496
- file_id: typing.Optional[str] = OMIT,
1497
1498
  request_options: typing.Optional[RequestOptions] = None,
1498
- ) -> HttpResponse[SingleUploadData]:
1499
+ ) -> HttpResponse[BatchUploadData]:
1499
1500
  """
1500
- Upload pre-computed embeddings for advanced similarity search.
1501
-
1502
- This endpoint accepts vector embeddings that you've generated externally, allowing you to integrate with custom embedding models or existing vector databases. The embeddings represent chunks of your content as numerical vectors.
1501
+ Upload multiple markdown/text documents simultaneously for efficient bulk processing.
1503
1502
 
1504
- The system stores these embeddings and makes them available for semantic search and similarity matching. Use this when you want to leverage specialized embedding models or have existing vector representations.
1503
+ This endpoint allows you to upload several markdown or text contents at once. Each content item gets processed asynchronously, and you can track the progress using their returned file IDs.
1505
1504
 
1506
1505
  Parameters
1507
1506
  ----------
1508
1507
  tenant_id : str
1509
1508
  Unique identifier for the tenant/organization
1510
1509
 
1511
- embeddings : typing.Sequence[typing.Sequence[float]]
1512
- The embeddings of source you want to index
1510
+ request : typing.Sequence[MarkdownUploadRequest]
1513
1511
 
1514
1512
  sub_tenant_id : typing.Optional[str]
1515
1513
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
1516
1514
 
1517
- file_id : typing.Optional[str]
1518
- The Source ID of the target source you want to index
1519
-
1520
1515
  request_options : typing.Optional[RequestOptions]
1521
1516
  Request-specific configuration.
1522
1517
 
1523
1518
  Returns
1524
1519
  -------
1525
- HttpResponse[SingleUploadData]
1520
+ HttpResponse[BatchUploadData]
1526
1521
  Successful Response
1527
1522
  """
1528
1523
  _response = self._client_wrapper.httpx_client.request(
1529
- "upload/upload_embeddings",
1524
+ "upload/batch_upload_markdown",
1530
1525
  method="POST",
1531
1526
  params={
1532
1527
  "tenant_id": tenant_id,
1533
1528
  "sub_tenant_id": sub_tenant_id,
1534
1529
  },
1535
- json={
1536
- "embeddings": embeddings,
1537
- "file_id": file_id,
1538
- },
1530
+ json=convert_and_respect_annotation_metadata(
1531
+ object_=request, annotation=typing.Sequence[MarkdownUploadRequest], direction="write"
1532
+ ),
1539
1533
  headers={
1540
1534
  "content-type": "application/json",
1541
1535
  },
@@ -1545,9 +1539,9 @@ class RawUploadClient:
1545
1539
  try:
1546
1540
  if 200 <= _response.status_code < 300:
1547
1541
  _data = typing.cast(
1548
- SingleUploadData,
1542
+ BatchUploadData,
1549
1543
  parse_obj_as(
1550
- type_=SingleUploadData, # type: ignore
1544
+ type_=BatchUploadData, # type: ignore
1551
1545
  object_=_response.json(),
1552
1546
  ),
1553
1547
  )
@@ -1634,50 +1628,47 @@ class RawUploadClient:
1634
1628
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1635
1629
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1636
1630
 
1637
- def update_embeddings(
1631
+ def batch_upload_text(
1638
1632
  self,
1639
1633
  *,
1640
1634
  tenant_id: str,
1635
+ request: typing.Sequence[MarkdownUploadRequest],
1641
1636
  sub_tenant_id: typing.Optional[str] = None,
1642
- embeddings: typing.Optional[typing.Dict[str, typing.Sequence[float]]] = OMIT,
1643
1637
  request_options: typing.Optional[RequestOptions] = None,
1644
- ) -> HttpResponse[SingleUploadData]:
1638
+ ) -> HttpResponse[BatchUploadData]:
1645
1639
  """
1646
- Update existing embeddings with new vector representations.
1640
+ Upload multiple markdown/text documents simultaneously for efficient bulk processing.
1647
1641
 
1648
- This endpoint allows you to modify embeddings that are already stored in your knowledge base. Provide updated vector representations for specific chunks of content, identified by their chunk IDs.
1649
-
1650
- The system will replace the existing embeddings with your new ones, ensuring that similarity searches reflect the most current vector representations. Use this when you need to update embeddings due to model improvements or content changes.
1642
+ This endpoint allows you to upload several markdown or text contents at once. Each content item gets processed asynchronously, and you can track the progress using their returned file IDs.
1651
1643
 
1652
1644
  Parameters
1653
1645
  ----------
1654
1646
  tenant_id : str
1655
1647
  Unique identifier for the tenant/organization
1656
1648
 
1649
+ request : typing.Sequence[MarkdownUploadRequest]
1650
+
1657
1651
  sub_tenant_id : typing.Optional[str]
1658
1652
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
1659
1653
 
1660
- embeddings : typing.Optional[typing.Dict[str, typing.Sequence[float]]]
1661
- The embeddings of source you want to index
1662
-
1663
1654
  request_options : typing.Optional[RequestOptions]
1664
1655
  Request-specific configuration.
1665
1656
 
1666
1657
  Returns
1667
1658
  -------
1668
- HttpResponse[SingleUploadData]
1659
+ HttpResponse[BatchUploadData]
1669
1660
  Successful Response
1670
1661
  """
1671
1662
  _response = self._client_wrapper.httpx_client.request(
1672
- "upload/update_embeddings",
1673
- method="PATCH",
1663
+ "upload/batch_upload_text",
1664
+ method="POST",
1674
1665
  params={
1675
1666
  "tenant_id": tenant_id,
1676
1667
  "sub_tenant_id": sub_tenant_id,
1677
1668
  },
1678
- json={
1679
- "embeddings": embeddings,
1680
- },
1669
+ json=convert_and_respect_annotation_metadata(
1670
+ object_=request, annotation=typing.Sequence[MarkdownUploadRequest], direction="write"
1671
+ ),
1681
1672
  headers={
1682
1673
  "content-type": "application/json",
1683
1674
  },
@@ -1687,9 +1678,9 @@ class RawUploadClient:
1687
1678
  try:
1688
1679
  if 200 <= _response.status_code < 300:
1689
1680
  _data = typing.cast(
1690
- SingleUploadData,
1681
+ BatchUploadData,
1691
1682
  parse_obj_as(
1692
- type_=SingleUploadData, # type: ignore
1683
+ type_=BatchUploadData, # type: ignore
1693
1684
  object_=_response.json(),
1694
1685
  ),
1695
1686
  )
@@ -1776,35 +1767,35 @@ class RawUploadClient:
1776
1767
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1777
1768
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1778
1769
 
1779
- def scrape_webpage(
1770
+ def upload_embeddings(
1780
1771
  self,
1781
1772
  *,
1782
- web_url: str,
1783
1773
  tenant_id: str,
1774
+ embeddings: typing.Sequence[typing.Sequence[float]],
1784
1775
  sub_tenant_id: typing.Optional[str] = None,
1785
- file_id: typing.Optional[str] = None,
1776
+ file_id: typing.Optional[str] = OMIT,
1786
1777
  request_options: typing.Optional[RequestOptions] = None,
1787
1778
  ) -> HttpResponse[SingleUploadData]:
1788
1779
  """
1789
- Extract and index content from web pages automatically.
1780
+ Upload pre-computed embeddings for advanced similarity search.
1790
1781
 
1791
- This endpoint initiates web scraping for the specified URL, extracting the main content, text, and structure from the webpage. It's perfect for capturing articles, documentation, or any web content you want to include in your knowledge base.
1782
+ This endpoint accepts vector embeddings that you've generated externally, allowing you to integrate with custom embedding models or existing vector databases. The embeddings represent chunks of your content as numerical vectors.
1792
1783
 
1793
- The system processes the webpage content asynchronously, cleaning and structuring the information for optimal search and retrieval. Use this when you need to add web content without manual copying and pasting.
1784
+ The system stores these embeddings and makes them available for semantic search and similarity matching. Use this when you want to leverage specialized embedding models or have existing vector representations.
1794
1785
 
1795
1786
  Parameters
1796
1787
  ----------
1797
- web_url : str
1798
- The URL of the webpage to scrape and index
1799
-
1800
1788
  tenant_id : str
1801
1789
  Unique identifier for the tenant/organization
1802
1790
 
1791
+ embeddings : typing.Sequence[typing.Sequence[float]]
1792
+ The embeddings of source you want to index
1793
+
1803
1794
  sub_tenant_id : typing.Optional[str]
1804
1795
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
1805
1796
 
1806
1797
  file_id : typing.Optional[str]
1807
- Optional custom file ID for the scraped content. If not provided, a unique ID will be generated
1798
+ The Source ID of the target source you want to index
1808
1799
 
1809
1800
  request_options : typing.Optional[RequestOptions]
1810
1801
  Request-specific configuration.
@@ -1815,17 +1806,18 @@ class RawUploadClient:
1815
1806
  Successful Response
1816
1807
  """
1817
1808
  _response = self._client_wrapper.httpx_client.request(
1818
- "upload/scrape_webpage",
1809
+ "upload/upload_embeddings",
1819
1810
  method="POST",
1820
1811
  params={
1821
- "web_url": web_url,
1822
1812
  "tenant_id": tenant_id,
1823
1813
  "sub_tenant_id": sub_tenant_id,
1814
+ },
1815
+ json={
1816
+ "embeddings": embeddings,
1824
1817
  "file_id": file_id,
1825
1818
  },
1826
- data={},
1827
1819
  headers={
1828
- "content-type": "application/x-www-form-urlencoded",
1820
+ "content-type": "application/json",
1829
1821
  },
1830
1822
  request_options=request_options,
1831
1823
  omit=OMIT,
@@ -1922,36 +1914,32 @@ class RawUploadClient:
1922
1914
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1923
1915
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1924
1916
 
1925
- def update_webpage(
1917
+ def update_embeddings(
1926
1918
  self,
1927
1919
  *,
1928
- web_url: str,
1929
- source_id: str,
1930
1920
  tenant_id: str,
1931
1921
  sub_tenant_id: typing.Optional[str] = None,
1922
+ embeddings: typing.Optional[typing.Dict[str, typing.Sequence[float]]] = OMIT,
1932
1923
  request_options: typing.Optional[RequestOptions] = None,
1933
1924
  ) -> HttpResponse[SingleUploadData]:
1934
1925
  """
1935
- Update web scraping content with fresh data from the source URL.
1926
+ Update existing embeddings with new vector representations.
1936
1927
 
1937
- This endpoint refreshes the content for an existing web scraping job. Provide the source ID of the webpage content you want to update, and the system will re-scrape the URL to capture any changes.
1928
+ This endpoint allows you to modify embeddings that are already stored in your knowledge base. Provide updated vector representations for specific chunks of content, identified by their chunk IDs.
1938
1929
 
1939
- The updated content gets processed asynchronously and re-indexed in your knowledge base. Use this to keep web content current when the source pages are frequently updated.
1930
+ The system will replace the existing embeddings with your new ones, ensuring that similarity searches reflect the most current vector representations. Use this when you need to update embeddings due to model improvements or content changes.
1940
1931
 
1941
1932
  Parameters
1942
1933
  ----------
1943
- web_url : str
1944
- The URL of the webpage to re-scrape
1945
-
1946
- source_id : str
1947
- The file ID of the existing web scraping job to update
1948
-
1949
1934
  tenant_id : str
1950
1935
  Unique identifier for the tenant/organization
1951
1936
 
1952
1937
  sub_tenant_id : typing.Optional[str]
1953
1938
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
1954
1939
 
1940
+ embeddings : typing.Optional[typing.Dict[str, typing.Sequence[float]]]
1941
+ The embeddings of source you want to index
1942
+
1955
1943
  request_options : typing.Optional[RequestOptions]
1956
1944
  Request-specific configuration.
1957
1945
 
@@ -1961,17 +1949,17 @@ class RawUploadClient:
1961
1949
  Successful Response
1962
1950
  """
1963
1951
  _response = self._client_wrapper.httpx_client.request(
1964
- "upload/update_webpage",
1952
+ "upload/update_embeddings",
1965
1953
  method="PATCH",
1966
1954
  params={
1967
- "web_url": web_url,
1968
- "source_id": source_id,
1969
1955
  "tenant_id": tenant_id,
1970
1956
  "sub_tenant_id": sub_tenant_id,
1971
1957
  },
1972
- data={},
1958
+ json={
1959
+ "embeddings": embeddings,
1960
+ },
1973
1961
  headers={
1974
- "content-type": "application/x-www-form-urlencoded",
1962
+ "content-type": "application/json",
1975
1963
  },
1976
1964
  request_options=request_options,
1977
1965
  omit=OMIT,
@@ -2068,66 +2056,114 @@ class RawUploadClient:
2068
2056
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2069
2057
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2070
2058
 
2071
- def delete_source(
2059
+ def scrape_webpage(
2072
2060
  self,
2073
2061
  *,
2062
+ web_url: str,
2074
2063
  tenant_id: str,
2075
- source_ids: typing.Sequence[str],
2076
- sub_tenant_id: typing.Optional[str] = OMIT,
2064
+ sub_tenant_id: typing.Optional[str] = None,
2065
+ file_id: typing.Optional[str] = None,
2077
2066
  request_options: typing.Optional[RequestOptions] = None,
2078
- ) -> HttpResponse[typing.Optional[typing.Any]]:
2067
+ ) -> HttpResponse[SingleUploadData]:
2079
2068
  """
2080
- Remove documents and content from your knowledge base.
2069
+ Extract and index content from web pages automatically.
2081
2070
 
2082
- This endpoint permanently deletes the specified sources from your knowledge base. Once deleted, the content will no longer be available for search or retrieval.
2071
+ This endpoint initiates web scraping for the specified URL, extracting the main content, text, and structure from the webpage. It's perfect for capturing articles, documentation, or any web content you want to include in your knowledge base.
2083
2072
 
2084
- Use this carefully as the action cannot be undone. The system will confirm successful deletion of each source ID you specify.
2073
+ The system processes the webpage content asynchronously, cleaning and structuring the information for optimal search and retrieval. Use this when you need to add web content without manual copying and pasting.
2085
2074
 
2086
2075
  Parameters
2087
2076
  ----------
2077
+ web_url : str
2078
+ The URL of the webpage to scrape and index
2079
+
2088
2080
  tenant_id : str
2089
2081
  Unique identifier for the tenant/organization
2090
2082
 
2091
- source_ids : typing.Sequence[str]
2092
- List of source IDs to delete
2093
-
2094
2083
  sub_tenant_id : typing.Optional[str]
2095
2084
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2096
2085
 
2086
+ file_id : typing.Optional[str]
2087
+ Optional custom file ID for the scraped content. If not provided, a unique ID will be generated
2088
+
2097
2089
  request_options : typing.Optional[RequestOptions]
2098
2090
  Request-specific configuration.
2099
2091
 
2100
2092
  Returns
2101
2093
  -------
2102
- HttpResponse[typing.Optional[typing.Any]]
2094
+ HttpResponse[SingleUploadData]
2103
2095
  Successful Response
2104
2096
  """
2105
2097
  _response = self._client_wrapper.httpx_client.request(
2106
- "upload/delete_source",
2107
- method="DELETE",
2108
- json={
2098
+ "upload/scrape_webpage",
2099
+ method="POST",
2100
+ params={
2101
+ "web_url": web_url,
2109
2102
  "tenant_id": tenant_id,
2110
- "source_ids": source_ids,
2111
2103
  "sub_tenant_id": sub_tenant_id,
2104
+ "file_id": file_id,
2112
2105
  },
2106
+ data={},
2113
2107
  headers={
2114
- "content-type": "application/json",
2108
+ "content-type": "application/x-www-form-urlencoded",
2115
2109
  },
2116
2110
  request_options=request_options,
2117
2111
  omit=OMIT,
2118
2112
  )
2119
2113
  try:
2120
- if _response is None or not _response.text.strip():
2121
- return HttpResponse(response=_response, data=None)
2122
2114
  if 200 <= _response.status_code < 300:
2123
2115
  _data = typing.cast(
2124
- typing.Optional[typing.Any],
2116
+ SingleUploadData,
2125
2117
  parse_obj_as(
2126
- type_=typing.Optional[typing.Any], # type: ignore
2118
+ type_=SingleUploadData, # type: ignore
2127
2119
  object_=_response.json(),
2128
2120
  ),
2129
2121
  )
2130
2122
  return HttpResponse(response=_response, data=_data)
2123
+ if _response.status_code == 400:
2124
+ raise BadRequestError(
2125
+ headers=dict(_response.headers),
2126
+ body=typing.cast(
2127
+ ActualErrorResponse,
2128
+ parse_obj_as(
2129
+ type_=ActualErrorResponse, # type: ignore
2130
+ object_=_response.json(),
2131
+ ),
2132
+ ),
2133
+ )
2134
+ if _response.status_code == 401:
2135
+ raise UnauthorizedError(
2136
+ headers=dict(_response.headers),
2137
+ body=typing.cast(
2138
+ ActualErrorResponse,
2139
+ parse_obj_as(
2140
+ type_=ActualErrorResponse, # type: ignore
2141
+ object_=_response.json(),
2142
+ ),
2143
+ ),
2144
+ )
2145
+ if _response.status_code == 403:
2146
+ raise ForbiddenError(
2147
+ headers=dict(_response.headers),
2148
+ body=typing.cast(
2149
+ ActualErrorResponse,
2150
+ parse_obj_as(
2151
+ type_=ActualErrorResponse, # type: ignore
2152
+ object_=_response.json(),
2153
+ ),
2154
+ ),
2155
+ )
2156
+ if _response.status_code == 404:
2157
+ raise NotFoundError(
2158
+ headers=dict(_response.headers),
2159
+ body=typing.cast(
2160
+ ActualErrorResponse,
2161
+ parse_obj_as(
2162
+ type_=ActualErrorResponse, # type: ignore
2163
+ object_=_response.json(),
2164
+ ),
2165
+ ),
2166
+ )
2131
2167
  if _response.status_code == 422:
2132
2168
  raise UnprocessableEntityError(
2133
2169
  headers=dict(_response.headers),
@@ -2139,34 +2175,60 @@ class RawUploadClient:
2139
2175
  ),
2140
2176
  ),
2141
2177
  )
2178
+ if _response.status_code == 500:
2179
+ raise InternalServerError(
2180
+ headers=dict(_response.headers),
2181
+ body=typing.cast(
2182
+ ActualErrorResponse,
2183
+ parse_obj_as(
2184
+ type_=ActualErrorResponse, # type: ignore
2185
+ object_=_response.json(),
2186
+ ),
2187
+ ),
2188
+ )
2189
+ if _response.status_code == 503:
2190
+ raise ServiceUnavailableError(
2191
+ headers=dict(_response.headers),
2192
+ body=typing.cast(
2193
+ ActualErrorResponse,
2194
+ parse_obj_as(
2195
+ type_=ActualErrorResponse, # type: ignore
2196
+ object_=_response.json(),
2197
+ ),
2198
+ ),
2199
+ )
2142
2200
  _response_json = _response.json()
2143
2201
  except JSONDecodeError:
2144
2202
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2145
2203
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2146
2204
 
2147
- def delete_memory(
2205
+ def update_webpage(
2148
2206
  self,
2149
2207
  *,
2208
+ web_url: str,
2209
+ source_id: str,
2150
2210
  tenant_id: str,
2151
- source_ids: typing.Sequence[str],
2152
- sub_tenant_id: typing.Optional[str] = OMIT,
2211
+ sub_tenant_id: typing.Optional[str] = None,
2153
2212
  request_options: typing.Optional[RequestOptions] = None,
2154
- ) -> HttpResponse[typing.Optional[typing.Any]]:
2213
+ ) -> HttpResponse[SingleUploadData]:
2155
2214
  """
2156
- Remove documents and content from your knowledge base.
2215
+ Update web scraping content with fresh data from the source URL.
2157
2216
 
2158
- This endpoint permanently deletes the specified sources from your knowledge base. Once deleted, the content will no longer be available for search or retrieval.
2217
+ This endpoint refreshes the content for an existing web scraping job. Provide the source ID of the webpage content you want to update, and the system will re-scrape the URL to capture any changes.
2159
2218
 
2160
- Use this carefully as the action cannot be undone. The system will confirm successful deletion of each source ID you specify.
2219
+ The updated content gets processed asynchronously and re-indexed in your knowledge base. Use this to keep web content current when the source pages are frequently updated.
2161
2220
 
2162
2221
  Parameters
2163
2222
  ----------
2223
+ web_url : str
2224
+ The URL of the webpage to re-scrape
2225
+
2226
+ source_id : str
2227
+ The file ID of the existing web scraping job to update
2228
+
2164
2229
  tenant_id : str
2165
2230
  Unique identifier for the tenant/organization
2166
2231
 
2167
- source_ids : typing.Sequence[str]
2168
- List of source IDs to delete
2169
-
2170
2232
  sub_tenant_id : typing.Optional[str]
2171
2233
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2172
2234
 
@@ -2175,35 +2237,79 @@ class RawUploadClient:
2175
2237
 
2176
2238
  Returns
2177
2239
  -------
2178
- HttpResponse[typing.Optional[typing.Any]]
2240
+ HttpResponse[SingleUploadData]
2179
2241
  Successful Response
2180
2242
  """
2181
2243
  _response = self._client_wrapper.httpx_client.request(
2182
- "upload/delete_memory",
2183
- method="DELETE",
2184
- json={
2244
+ "upload/update_webpage",
2245
+ method="PATCH",
2246
+ params={
2247
+ "web_url": web_url,
2248
+ "source_id": source_id,
2185
2249
  "tenant_id": tenant_id,
2186
- "source_ids": source_ids,
2187
2250
  "sub_tenant_id": sub_tenant_id,
2188
2251
  },
2252
+ data={},
2189
2253
  headers={
2190
- "content-type": "application/json",
2254
+ "content-type": "application/x-www-form-urlencoded",
2191
2255
  },
2192
2256
  request_options=request_options,
2193
2257
  omit=OMIT,
2194
2258
  )
2195
2259
  try:
2196
- if _response is None or not _response.text.strip():
2197
- return HttpResponse(response=_response, data=None)
2198
2260
  if 200 <= _response.status_code < 300:
2199
2261
  _data = typing.cast(
2200
- typing.Optional[typing.Any],
2262
+ SingleUploadData,
2201
2263
  parse_obj_as(
2202
- type_=typing.Optional[typing.Any], # type: ignore
2264
+ type_=SingleUploadData, # type: ignore
2203
2265
  object_=_response.json(),
2204
2266
  ),
2205
2267
  )
2206
2268
  return HttpResponse(response=_response, data=_data)
2269
+ if _response.status_code == 400:
2270
+ raise BadRequestError(
2271
+ headers=dict(_response.headers),
2272
+ body=typing.cast(
2273
+ ActualErrorResponse,
2274
+ parse_obj_as(
2275
+ type_=ActualErrorResponse, # type: ignore
2276
+ object_=_response.json(),
2277
+ ),
2278
+ ),
2279
+ )
2280
+ if _response.status_code == 401:
2281
+ raise UnauthorizedError(
2282
+ headers=dict(_response.headers),
2283
+ body=typing.cast(
2284
+ ActualErrorResponse,
2285
+ parse_obj_as(
2286
+ type_=ActualErrorResponse, # type: ignore
2287
+ object_=_response.json(),
2288
+ ),
2289
+ ),
2290
+ )
2291
+ if _response.status_code == 403:
2292
+ raise ForbiddenError(
2293
+ headers=dict(_response.headers),
2294
+ body=typing.cast(
2295
+ ActualErrorResponse,
2296
+ parse_obj_as(
2297
+ type_=ActualErrorResponse, # type: ignore
2298
+ object_=_response.json(),
2299
+ ),
2300
+ ),
2301
+ )
2302
+ if _response.status_code == 404:
2303
+ raise NotFoundError(
2304
+ headers=dict(_response.headers),
2305
+ body=typing.cast(
2306
+ ActualErrorResponse,
2307
+ parse_obj_as(
2308
+ type_=ActualErrorResponse, # type: ignore
2309
+ object_=_response.json(),
2310
+ ),
2311
+ ),
2312
+ )
2207
2313
  if _response.status_code == 422:
2208
2314
  raise UnprocessableEntityError(
2209
2315
  headers=dict(_response.headers),
@@ -2215,34 +2321,197 @@ class RawUploadClient:
2215
2321
  ),
2216
2322
  ),
2217
2323
  )
2324
+ if _response.status_code == 500:
2325
+ raise InternalServerError(
2326
+ headers=dict(_response.headers),
2327
+ body=typing.cast(
2328
+ ActualErrorResponse,
2329
+ parse_obj_as(
2330
+ type_=ActualErrorResponse, # type: ignore
2331
+ object_=_response.json(),
2332
+ ),
2333
+ ),
2334
+ )
2335
+ if _response.status_code == 503:
2336
+ raise ServiceUnavailableError(
2337
+ headers=dict(_response.headers),
2338
+ body=typing.cast(
2339
+ ActualErrorResponse,
2340
+ parse_obj_as(
2341
+ type_=ActualErrorResponse, # type: ignore
2342
+ object_=_response.json(),
2343
+ ),
2344
+ ),
2345
+ )
2218
2346
  _response_json = _response.json()
2219
2347
  except JSONDecodeError:
2220
2348
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2221
2349
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2222
2350
 
2223
- def verify_processing(
2351
+ def batch_scrape_webpage(
2224
2352
  self,
2225
2353
  *,
2226
- file_id: str,
2227
- tenant_id: typing.Optional[str] = None,
2354
+ tenant_id: str,
2355
+ request: typing.Sequence[WebpageScrapeRequest],
2228
2356
  sub_tenant_id: typing.Optional[str] = None,
2229
2357
  request_options: typing.Optional[RequestOptions] = None,
2230
- ) -> HttpResponse[ProcessingStatus]:
2358
+ ) -> HttpResponse[BatchUploadData]:
2231
2359
  """
2232
- Check the current processing status of your uploaded content.
2360
+ Extract and index content from multiple web pages simultaneously.
2233
2361
 
2234
- This endpoint allows you to monitor the progress of documents, text, or other content you've uploaded. Simply provide the file ID to see whether processing is complete, still in progress, or if any errors occurred.
2362
+ This endpoint initiates web scraping for multiple URLs at once, extracting the main content, text, and structure from each webpage. It's perfect for capturing multiple articles, documentation pages, or any web content you want to include in your knowledge base.
2235
2363
 
2236
- Use this to determine when your content is ready for search and retrieval, or to troubleshoot any processing issues.
2364
+ The system processes all webpage content asynchronously, cleaning and structuring the information for optimal search and retrieval.
2237
2365
 
2238
2366
  Parameters
2239
2367
  ----------
2240
- file_id : str
2241
- The file ID to check processing status for
2368
+ tenant_id : str
2369
+ Unique identifier for the tenant/organization
2242
2370
 
2243
- tenant_id : typing.Optional[str]
2371
+ request : typing.Sequence[WebpageScrapeRequest]
2372
+
2373
+ sub_tenant_id : typing.Optional[str]
2374
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2375
+
2376
+ request_options : typing.Optional[RequestOptions]
2377
+ Request-specific configuration.
2378
+
2379
+ Returns
2380
+ -------
2381
+ HttpResponse[BatchUploadData]
2382
+ Successful Response
2383
+ """
2384
+ _response = self._client_wrapper.httpx_client.request(
2385
+ "upload/batch_scrape_webpage",
2386
+ method="POST",
2387
+ params={
2388
+ "tenant_id": tenant_id,
2389
+ "sub_tenant_id": sub_tenant_id,
2390
+ },
2391
+ json=convert_and_respect_annotation_metadata(
2392
+ object_=request, annotation=typing.Sequence[WebpageScrapeRequest], direction="write"
2393
+ ),
2394
+ headers={
2395
+ "content-type": "application/json",
2396
+ },
2397
+ request_options=request_options,
2398
+ omit=OMIT,
2399
+ )
2400
+ try:
2401
+ if 200 <= _response.status_code < 300:
2402
+ _data = typing.cast(
2403
+ BatchUploadData,
2404
+ parse_obj_as(
2405
+ type_=BatchUploadData, # type: ignore
2406
+ object_=_response.json(),
2407
+ ),
2408
+ )
2409
+ return HttpResponse(response=_response, data=_data)
2410
+ if _response.status_code == 400:
2411
+ raise BadRequestError(
2412
+ headers=dict(_response.headers),
2413
+ body=typing.cast(
2414
+ ActualErrorResponse,
2415
+ parse_obj_as(
2416
+ type_=ActualErrorResponse, # type: ignore
2417
+ object_=_response.json(),
2418
+ ),
2419
+ ),
2420
+ )
2421
+ if _response.status_code == 401:
2422
+ raise UnauthorizedError(
2423
+ headers=dict(_response.headers),
2424
+ body=typing.cast(
2425
+ ActualErrorResponse,
2426
+ parse_obj_as(
2427
+ type_=ActualErrorResponse, # type: ignore
2428
+ object_=_response.json(),
2429
+ ),
2430
+ ),
2431
+ )
2432
+ if _response.status_code == 403:
2433
+ raise ForbiddenError(
2434
+ headers=dict(_response.headers),
2435
+ body=typing.cast(
2436
+ ActualErrorResponse,
2437
+ parse_obj_as(
2438
+ type_=ActualErrorResponse, # type: ignore
2439
+ object_=_response.json(),
2440
+ ),
2441
+ ),
2442
+ )
2443
+ if _response.status_code == 404:
2444
+ raise NotFoundError(
2445
+ headers=dict(_response.headers),
2446
+ body=typing.cast(
2447
+ ActualErrorResponse,
2448
+ parse_obj_as(
2449
+ type_=ActualErrorResponse, # type: ignore
2450
+ object_=_response.json(),
2451
+ ),
2452
+ ),
2453
+ )
2454
+ if _response.status_code == 422:
2455
+ raise UnprocessableEntityError(
2456
+ headers=dict(_response.headers),
2457
+ body=typing.cast(
2458
+ typing.Optional[typing.Any],
2459
+ parse_obj_as(
2460
+ type_=typing.Optional[typing.Any], # type: ignore
2461
+ object_=_response.json(),
2462
+ ),
2463
+ ),
2464
+ )
2465
+ if _response.status_code == 500:
2466
+ raise InternalServerError(
2467
+ headers=dict(_response.headers),
2468
+ body=typing.cast(
2469
+ ActualErrorResponse,
2470
+ parse_obj_as(
2471
+ type_=ActualErrorResponse, # type: ignore
2472
+ object_=_response.json(),
2473
+ ),
2474
+ ),
2475
+ )
2476
+ if _response.status_code == 503:
2477
+ raise ServiceUnavailableError(
2478
+ headers=dict(_response.headers),
2479
+ body=typing.cast(
2480
+ ActualErrorResponse,
2481
+ parse_obj_as(
2482
+ type_=ActualErrorResponse, # type: ignore
2483
+ object_=_response.json(),
2484
+ ),
2485
+ ),
2486
+ )
2487
+ _response_json = _response.json()
2488
+ except JSONDecodeError:
2489
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2490
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2491
+
2492
+ def delete_source(
2493
+ self,
2494
+ *,
2495
+ tenant_id: str,
2496
+ source_ids: typing.Sequence[str],
2497
+ sub_tenant_id: typing.Optional[str] = OMIT,
2498
+ request_options: typing.Optional[RequestOptions] = None,
2499
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
2500
+ """
2501
+ Remove documents and content from your knowledge base.
2502
+
2503
+ This endpoint permanently deletes the specified sources from your knowledge base. Once deleted, the content will no longer be available for search or retrieval.
2504
+
2505
+ Use this carefully as the action cannot be undone. The system will confirm successful deletion of each source ID you specify.
2506
+
2507
+ Parameters
2508
+ ----------
2509
+ tenant_id : str
2244
2510
  Unique identifier for the tenant/organization
2245
2511
 
2512
+ source_ids : typing.Sequence[str]
2513
+ List of source IDs to delete
2514
+
2246
2515
  sub_tenant_id : typing.Optional[str]
2247
2516
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2248
2517
 
@@ -2251,29 +2520,514 @@ class RawUploadClient:
2251
2520
 
2252
2521
  Returns
2253
2522
  -------
2254
- HttpResponse[ProcessingStatus]
2523
+ HttpResponse[typing.Optional[typing.Any]]
2524
+ Successful Response
2525
+ """
2526
+ _response = self._client_wrapper.httpx_client.request(
2527
+ "upload/delete_source",
2528
+ method="DELETE",
2529
+ json={
2530
+ "tenant_id": tenant_id,
2531
+ "source_ids": source_ids,
2532
+ "sub_tenant_id": sub_tenant_id,
2533
+ },
2534
+ headers={
2535
+ "content-type": "application/json",
2536
+ },
2537
+ request_options=request_options,
2538
+ omit=OMIT,
2539
+ )
2540
+ try:
2541
+ if _response is None or not _response.text.strip():
2542
+ return HttpResponse(response=_response, data=None)
2543
+ if 200 <= _response.status_code < 300:
2544
+ _data = typing.cast(
2545
+ typing.Optional[typing.Any],
2546
+ parse_obj_as(
2547
+ type_=typing.Optional[typing.Any], # type: ignore
2548
+ object_=_response.json(),
2549
+ ),
2550
+ )
2551
+ return HttpResponse(response=_response, data=_data)
2552
+ if _response.status_code == 422:
2553
+ raise UnprocessableEntityError(
2554
+ headers=dict(_response.headers),
2555
+ body=typing.cast(
2556
+ typing.Optional[typing.Any],
2557
+ parse_obj_as(
2558
+ type_=typing.Optional[typing.Any], # type: ignore
2559
+ object_=_response.json(),
2560
+ ),
2561
+ ),
2562
+ )
2563
+ _response_json = _response.json()
2564
+ except JSONDecodeError:
2565
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2566
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2567
+
2568
+ def delete_memory(
2569
+ self,
2570
+ *,
2571
+ tenant_id: str,
2572
+ source_ids: typing.Sequence[str],
2573
+ sub_tenant_id: typing.Optional[str] = OMIT,
2574
+ request_options: typing.Optional[RequestOptions] = None,
2575
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
2576
+ """
2577
+ Remove documents and content from your knowledge base.
2578
+
2579
+ This endpoint permanently deletes the specified sources from your knowledge base. Once deleted, the content will no longer be available for search or retrieval.
2580
+
2581
+ Use this carefully as the action cannot be undone. The system will confirm successful deletion of each source ID you specify.
2582
+
2583
+ Parameters
2584
+ ----------
2585
+ tenant_id : str
2586
+ Unique identifier for the tenant/organization
2587
+
2588
+ source_ids : typing.Sequence[str]
2589
+ List of source IDs to delete
2590
+
2591
+ sub_tenant_id : typing.Optional[str]
2592
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2593
+
2594
+ request_options : typing.Optional[RequestOptions]
2595
+ Request-specific configuration.
2596
+
2597
+ Returns
2598
+ -------
2599
+ HttpResponse[typing.Optional[typing.Any]]
2600
+ Successful Response
2601
+ """
2602
+ _response = self._client_wrapper.httpx_client.request(
2603
+ "upload/delete_memory",
2604
+ method="DELETE",
2605
+ json={
2606
+ "tenant_id": tenant_id,
2607
+ "source_ids": source_ids,
2608
+ "sub_tenant_id": sub_tenant_id,
2609
+ },
2610
+ headers={
2611
+ "content-type": "application/json",
2612
+ },
2613
+ request_options=request_options,
2614
+ omit=OMIT,
2615
+ )
2616
+ try:
2617
+ if _response is None or not _response.text.strip():
2618
+ return HttpResponse(response=_response, data=None)
2619
+ if 200 <= _response.status_code < 300:
2620
+ _data = typing.cast(
2621
+ typing.Optional[typing.Any],
2622
+ parse_obj_as(
2623
+ type_=typing.Optional[typing.Any], # type: ignore
2624
+ object_=_response.json(),
2625
+ ),
2626
+ )
2627
+ return HttpResponse(response=_response, data=_data)
2628
+ if _response.status_code == 422:
2629
+ raise UnprocessableEntityError(
2630
+ headers=dict(_response.headers),
2631
+ body=typing.cast(
2632
+ typing.Optional[typing.Any],
2633
+ parse_obj_as(
2634
+ type_=typing.Optional[typing.Any], # type: ignore
2635
+ object_=_response.json(),
2636
+ ),
2637
+ ),
2638
+ )
2639
+ _response_json = _response.json()
2640
+ except JSONDecodeError:
2641
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2642
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2643
+
2644
+ def verify_processing(
2645
+ self,
2646
+ *,
2647
+ file_id: str,
2648
+ tenant_id: typing.Optional[str] = None,
2649
+ sub_tenant_id: typing.Optional[str] = None,
2650
+ request_options: typing.Optional[RequestOptions] = None,
2651
+ ) -> HttpResponse[ProcessingStatus]:
2652
+ """
2653
+ Check the current processing status of your uploaded content.
2654
+
2655
+ This endpoint allows you to monitor the progress of documents, text, or other content you've uploaded. Simply provide the file ID to see whether processing is complete, still in progress, or if any errors occurred.
2656
+
2657
+ Use this to determine when your content is ready for search and retrieval, or to troubleshoot any processing issues.
2658
+
2659
+ Parameters
2660
+ ----------
2661
+ file_id : str
2662
+ The file ID to check processing status for
2663
+
2664
+ tenant_id : typing.Optional[str]
2665
+ Unique identifier for the tenant/organization
2666
+
2667
+ sub_tenant_id : typing.Optional[str]
2668
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2669
+
2670
+ request_options : typing.Optional[RequestOptions]
2671
+ Request-specific configuration.
2672
+
2673
+ Returns
2674
+ -------
2675
+ HttpResponse[ProcessingStatus]
2676
+ Successful Response
2677
+ """
2678
+ _response = self._client_wrapper.httpx_client.request(
2679
+ "upload/verify_processing",
2680
+ method="POST",
2681
+ params={
2682
+ "file_id": file_id,
2683
+ "tenant_id": tenant_id,
2684
+ "sub_tenant_id": sub_tenant_id,
2685
+ },
2686
+ request_options=request_options,
2687
+ )
2688
+ try:
2689
+ if 200 <= _response.status_code < 300:
2690
+ _data = typing.cast(
2691
+ ProcessingStatus,
2692
+ parse_obj_as(
2693
+ type_=ProcessingStatus, # type: ignore
2694
+ object_=_response.json(),
2695
+ ),
2696
+ )
2697
+ return HttpResponse(response=_response, data=_data)
2698
+ if _response.status_code == 400:
2699
+ raise BadRequestError(
2700
+ headers=dict(_response.headers),
2701
+ body=typing.cast(
2702
+ ActualErrorResponse,
2703
+ parse_obj_as(
2704
+ type_=ActualErrorResponse, # type: ignore
2705
+ object_=_response.json(),
2706
+ ),
2707
+ ),
2708
+ )
2709
+ if _response.status_code == 401:
2710
+ raise UnauthorizedError(
2711
+ headers=dict(_response.headers),
2712
+ body=typing.cast(
2713
+ ActualErrorResponse,
2714
+ parse_obj_as(
2715
+ type_=ActualErrorResponse, # type: ignore
2716
+ object_=_response.json(),
2717
+ ),
2718
+ ),
2719
+ )
2720
+ if _response.status_code == 403:
2721
+ raise ForbiddenError(
2722
+ headers=dict(_response.headers),
2723
+ body=typing.cast(
2724
+ ActualErrorResponse,
2725
+ parse_obj_as(
2726
+ type_=ActualErrorResponse, # type: ignore
2727
+ object_=_response.json(),
2728
+ ),
2729
+ ),
2730
+ )
2731
+ if _response.status_code == 404:
2732
+ raise NotFoundError(
2733
+ headers=dict(_response.headers),
2734
+ body=typing.cast(
2735
+ ActualErrorResponse,
2736
+ parse_obj_as(
2737
+ type_=ActualErrorResponse, # type: ignore
2738
+ object_=_response.json(),
2739
+ ),
2740
+ ),
2741
+ )
2742
+ if _response.status_code == 422:
2743
+ raise UnprocessableEntityError(
2744
+ headers=dict(_response.headers),
2745
+ body=typing.cast(
2746
+ typing.Optional[typing.Any],
2747
+ parse_obj_as(
2748
+ type_=typing.Optional[typing.Any], # type: ignore
2749
+ object_=_response.json(),
2750
+ ),
2751
+ ),
2752
+ )
2753
+ if _response.status_code == 500:
2754
+ raise InternalServerError(
2755
+ headers=dict(_response.headers),
2756
+ body=typing.cast(
2757
+ ActualErrorResponse,
2758
+ parse_obj_as(
2759
+ type_=ActualErrorResponse, # type: ignore
2760
+ object_=_response.json(),
2761
+ ),
2762
+ ),
2763
+ )
2764
+ if _response.status_code == 503:
2765
+ raise ServiceUnavailableError(
2766
+ headers=dict(_response.headers),
2767
+ body=typing.cast(
2768
+ ActualErrorResponse,
2769
+ parse_obj_as(
2770
+ type_=ActualErrorResponse, # type: ignore
2771
+ object_=_response.json(),
2772
+ ),
2773
+ ),
2774
+ )
2775
+ _response_json = _response.json()
2776
+ except JSONDecodeError:
2777
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2778
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2779
+
2780
+
2781
+ class AsyncRawUploadClient:
2782
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
2783
+ self._client_wrapper = client_wrapper
2784
+
2785
+ async def batch_upload(
2786
+ self,
2787
+ *,
2788
+ tenant_id: str,
2789
+ files: typing.List[core.File],
2790
+ sub_tenant_id: typing.Optional[str] = None,
2791
+ file_ids: typing.Optional[str] = OMIT,
2792
+ tenant_metadata: typing.Optional[str] = OMIT,
2793
+ document_metadata: typing.Optional[str] = OMIT,
2794
+ request_options: typing.Optional[RequestOptions] = None,
2795
+ ) -> AsyncHttpResponse[BatchUploadData]:
2796
+ """
2797
+ Upload multiple documents simultaneously for efficient bulk processing.
2798
+
2799
+ This endpoint allows you to upload several files at once, which is ideal for large document collections or periodic data imports. Each file gets processed asynchronously, and you can track the progress of individual files using their returned file IDs.
2800
+
2801
+ The system automatically handles file parsing, content extraction, and indexing across all uploaded documents. You'll receive confirmation once all files are queued for processing.
2802
+
2803
+ Parameters
2804
+ ----------
2805
+ tenant_id : str
2806
+ Unique identifier for the tenant/organization
2807
+
2808
+ files : typing.List[core.File]
2809
+ See core.File for more documentation
2810
+
2811
+ sub_tenant_id : typing.Optional[str]
2812
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2813
+
2814
+ file_ids : typing.Optional[str]
2815
+ Optional JSON string array of file IDs for the uploaded content. If not provided or empty, will be generated automatically.
2816
+
2817
+ tenant_metadata : typing.Optional[str]
2818
+ JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
2819
+
2820
+ Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
2821
+
2822
+
2823
+ document_metadata : typing.Optional[str]
2824
+ JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
2825
+
2826
+ Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
2827
+
2828
+
2829
+
2830
+ request_options : typing.Optional[RequestOptions]
2831
+ Request-specific configuration.
2832
+
2833
+ Returns
2834
+ -------
2835
+ AsyncHttpResponse[BatchUploadData]
2836
+ Successful Response
2837
+ """
2838
+ _response = await self._client_wrapper.httpx_client.request(
2839
+ "upload/batch_upload",
2840
+ method="POST",
2841
+ params={
2842
+ "tenant_id": tenant_id,
2843
+ "sub_tenant_id": sub_tenant_id,
2844
+ },
2845
+ data={
2846
+ "file_ids": file_ids,
2847
+ "tenant_metadata": tenant_metadata,
2848
+ "document_metadata": document_metadata,
2849
+ },
2850
+ files={
2851
+ "files": files,
2852
+ },
2853
+ request_options=request_options,
2854
+ omit=OMIT,
2855
+ force_multipart=True,
2856
+ )
2857
+ try:
2858
+ if 200 <= _response.status_code < 300:
2859
+ _data = typing.cast(
2860
+ BatchUploadData,
2861
+ parse_obj_as(
2862
+ type_=BatchUploadData, # type: ignore
2863
+ object_=_response.json(),
2864
+ ),
2865
+ )
2866
+ return AsyncHttpResponse(response=_response, data=_data)
2867
+ if _response.status_code == 400:
2868
+ raise BadRequestError(
2869
+ headers=dict(_response.headers),
2870
+ body=typing.cast(
2871
+ ActualErrorResponse,
2872
+ parse_obj_as(
2873
+ type_=ActualErrorResponse, # type: ignore
2874
+ object_=_response.json(),
2875
+ ),
2876
+ ),
2877
+ )
2878
+ if _response.status_code == 401:
2879
+ raise UnauthorizedError(
2880
+ headers=dict(_response.headers),
2881
+ body=typing.cast(
2882
+ ActualErrorResponse,
2883
+ parse_obj_as(
2884
+ type_=ActualErrorResponse, # type: ignore
2885
+ object_=_response.json(),
2886
+ ),
2887
+ ),
2888
+ )
2889
+ if _response.status_code == 403:
2890
+ raise ForbiddenError(
2891
+ headers=dict(_response.headers),
2892
+ body=typing.cast(
2893
+ ActualErrorResponse,
2894
+ parse_obj_as(
2895
+ type_=ActualErrorResponse, # type: ignore
2896
+ object_=_response.json(),
2897
+ ),
2898
+ ),
2899
+ )
2900
+ if _response.status_code == 404:
2901
+ raise NotFoundError(
2902
+ headers=dict(_response.headers),
2903
+ body=typing.cast(
2904
+ ActualErrorResponse,
2905
+ parse_obj_as(
2906
+ type_=ActualErrorResponse, # type: ignore
2907
+ object_=_response.json(),
2908
+ ),
2909
+ ),
2910
+ )
2911
+ if _response.status_code == 422:
2912
+ raise UnprocessableEntityError(
2913
+ headers=dict(_response.headers),
2914
+ body=typing.cast(
2915
+ typing.Optional[typing.Any],
2916
+ parse_obj_as(
2917
+ type_=typing.Optional[typing.Any], # type: ignore
2918
+ object_=_response.json(),
2919
+ ),
2920
+ ),
2921
+ )
2922
+ if _response.status_code == 500:
2923
+ raise InternalServerError(
2924
+ headers=dict(_response.headers),
2925
+ body=typing.cast(
2926
+ ActualErrorResponse,
2927
+ parse_obj_as(
2928
+ type_=ActualErrorResponse, # type: ignore
2929
+ object_=_response.json(),
2930
+ ),
2931
+ ),
2932
+ )
2933
+ if _response.status_code == 503:
2934
+ raise ServiceUnavailableError(
2935
+ headers=dict(_response.headers),
2936
+ body=typing.cast(
2937
+ ActualErrorResponse,
2938
+ parse_obj_as(
2939
+ type_=ActualErrorResponse, # type: ignore
2940
+ object_=_response.json(),
2941
+ ),
2942
+ ),
2943
+ )
2944
+ _response_json = _response.json()
2945
+ except JSONDecodeError:
2946
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2947
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2948
+
2949
+ async def batch_update(
2950
+ self,
2951
+ *,
2952
+ tenant_id: str,
2953
+ files: typing.List[core.File],
2954
+ sub_tenant_id: typing.Optional[str] = None,
2955
+ source_ids: typing.Optional[typing.List[str]] = OMIT,
2956
+ tenant_metadata: typing.Optional[str] = OMIT,
2957
+ document_metadata: typing.Optional[str] = OMIT,
2958
+ request_options: typing.Optional[RequestOptions] = None,
2959
+ ) -> AsyncHttpResponse[BatchUploadData]:
2960
+ """
2961
+ Update multiple existing documents with new content and metadata.
2962
+
2963
+ Use this endpoint when you need to replace or modify several documents that are already in your knowledge base. Each file must correspond to an existing source ID, ensuring that updates are applied to the correct documents.
2964
+
2965
+ The system processes updates asynchronously, allowing you to continue working while your documents are re-indexed. Track the progress using the returned file IDs to know when updates are complete.
2966
+
2967
+ Parameters
2968
+ ----------
2969
+ tenant_id : str
2970
+ Unique identifier for the tenant/organization
2971
+
2972
+ files : typing.List[core.File]
2973
+ See core.File for more documentation
2974
+
2975
+ sub_tenant_id : typing.Optional[str]
2976
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2977
+
2978
+ source_ids : typing.Optional[typing.List[str]]
2979
+ List of source IDs corresponding to the files being updated
2980
+
2981
+ tenant_metadata : typing.Optional[str]
2982
+ JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
2983
+
2984
+ Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
2985
+
2986
+
2987
+ document_metadata : typing.Optional[str]
2988
+ JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
2989
+
2990
+ Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
2991
+
2992
+
2993
+
2994
+ request_options : typing.Optional[RequestOptions]
2995
+ Request-specific configuration.
2996
+
2997
+ Returns
2998
+ -------
2999
+ AsyncHttpResponse[BatchUploadData]
2255
3000
  Successful Response
2256
3001
  """
2257
- _response = self._client_wrapper.httpx_client.request(
2258
- "upload/verify_processing",
2259
- method="POST",
3002
+ _response = await self._client_wrapper.httpx_client.request(
3003
+ "upload/batch_update",
3004
+ method="PATCH",
2260
3005
  params={
2261
- "file_id": file_id,
2262
3006
  "tenant_id": tenant_id,
2263
3007
  "sub_tenant_id": sub_tenant_id,
2264
3008
  },
3009
+ data={
3010
+ "source_ids": source_ids,
3011
+ "tenant_metadata": tenant_metadata,
3012
+ "document_metadata": document_metadata,
3013
+ },
3014
+ files={
3015
+ "files": files,
3016
+ },
2265
3017
  request_options=request_options,
3018
+ omit=OMIT,
3019
+ force_multipart=True,
2266
3020
  )
2267
3021
  try:
2268
3022
  if 200 <= _response.status_code < 300:
2269
3023
  _data = typing.cast(
2270
- ProcessingStatus,
3024
+ BatchUploadData,
2271
3025
  parse_obj_as(
2272
- type_=ProcessingStatus, # type: ignore
3026
+ type_=BatchUploadData, # type: ignore
2273
3027
  object_=_response.json(),
2274
3028
  ),
2275
3029
  )
2276
- return HttpResponse(response=_response, data=_data)
3030
+ return AsyncHttpResponse(response=_response, data=_data)
2277
3031
  if _response.status_code == 400:
2278
3032
  raise BadRequestError(
2279
3033
  headers=dict(_response.headers),
@@ -2356,42 +3110,37 @@ class RawUploadClient:
2356
3110
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2357
3111
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2358
3112
 
2359
-
2360
- class AsyncRawUploadClient:
2361
- def __init__(self, *, client_wrapper: AsyncClientWrapper):
2362
- self._client_wrapper = client_wrapper
2363
-
2364
- async def batch_upload(
3113
+ async def upload_document(
2365
3114
  self,
2366
3115
  *,
2367
3116
  tenant_id: str,
2368
- files: typing.List[core.File],
3117
+ file: core.File,
2369
3118
  sub_tenant_id: typing.Optional[str] = None,
2370
- file_ids: typing.Optional[str] = OMIT,
3119
+ file_id: typing.Optional[str] = OMIT,
2371
3120
  tenant_metadata: typing.Optional[str] = OMIT,
2372
3121
  document_metadata: typing.Optional[str] = OMIT,
2373
3122
  request_options: typing.Optional[RequestOptions] = None,
2374
- ) -> AsyncHttpResponse[BatchUploadData]:
3123
+ ) -> AsyncHttpResponse[SingleUploadData]:
2375
3124
  """
2376
- Upload multiple documents simultaneously for efficient bulk processing.
3125
+ Upload a single document for processing and indexing into your knowledge base.
2377
3126
 
2378
- This endpoint allows you to upload several files at once, which is ideal for large document collections or periodic data imports. Each file gets processed asynchronously, and you can track the progress of individual files using their returned file IDs.
3127
+ This endpoint accepts documents in various formats and processes them for search and retrieval. You can include custom metadata to help organize and categorize your content.
2379
3128
 
2380
- The system automatically handles file parsing, content extraction, and indexing across all uploaded documents. You'll receive confirmation once all files are queued for processing.
3129
+ The system extracts text content, processes it asynchronously, and makes it available for search queries. You can track the processing status using the returned file ID.
2381
3130
 
2382
3131
  Parameters
2383
3132
  ----------
2384
3133
  tenant_id : str
2385
3134
  Unique identifier for the tenant/organization
2386
3135
 
2387
- files : typing.List[core.File]
3136
+ file : core.File
2388
3137
  See core.File for more documentation
2389
3138
 
2390
3139
  sub_tenant_id : typing.Optional[str]
2391
3140
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2392
3141
 
2393
- file_ids : typing.Optional[str]
2394
- Optional JSON string array of file IDs for the uploaded content. If not provided or empty, will be generated automatically.
3142
+ file_id : typing.Optional[str]
3143
+ Optional file ID for the uploaded content. If not provided, will be generated automatically.
2395
3144
 
2396
3145
  tenant_metadata : typing.Optional[str]
2397
3146
  JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
@@ -2411,23 +3160,23 @@ class AsyncRawUploadClient:
2411
3160
 
2412
3161
  Returns
2413
3162
  -------
2414
- AsyncHttpResponse[BatchUploadData]
3163
+ AsyncHttpResponse[SingleUploadData]
2415
3164
  Successful Response
2416
3165
  """
2417
3166
  _response = await self._client_wrapper.httpx_client.request(
2418
- "upload/batch_upload",
3167
+ "upload/upload_document",
2419
3168
  method="POST",
2420
3169
  params={
2421
3170
  "tenant_id": tenant_id,
2422
3171
  "sub_tenant_id": sub_tenant_id,
2423
3172
  },
2424
3173
  data={
2425
- "file_ids": file_ids,
3174
+ "file_id": file_id,
2426
3175
  "tenant_metadata": tenant_metadata,
2427
3176
  "document_metadata": document_metadata,
2428
3177
  },
2429
3178
  files={
2430
- "files": files,
3179
+ "file": file,
2431
3180
  },
2432
3181
  request_options=request_options,
2433
3182
  omit=OMIT,
@@ -2436,9 +3185,9 @@ class AsyncRawUploadClient:
2436
3185
  try:
2437
3186
  if 200 <= _response.status_code < 300:
2438
3187
  _data = typing.cast(
2439
- BatchUploadData,
3188
+ SingleUploadData,
2440
3189
  parse_obj_as(
2441
- type_=BatchUploadData, # type: ignore
3190
+ type_=SingleUploadData, # type: ignore
2442
3191
  object_=_response.json(),
2443
3192
  ),
2444
3193
  )
@@ -2525,38 +3274,38 @@ class AsyncRawUploadClient:
2525
3274
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2526
3275
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2527
3276
 
2528
- async def batch_update(
3277
+ async def update_document(
2529
3278
  self,
2530
3279
  *,
3280
+ source_id: str,
2531
3281
  tenant_id: str,
2532
- files: typing.List[core.File],
3282
+ file: core.File,
2533
3283
  sub_tenant_id: typing.Optional[str] = None,
2534
- source_ids: typing.Optional[typing.List[str]] = OMIT,
2535
3284
  tenant_metadata: typing.Optional[str] = OMIT,
2536
3285
  document_metadata: typing.Optional[str] = OMIT,
2537
3286
  request_options: typing.Optional[RequestOptions] = None,
2538
- ) -> AsyncHttpResponse[BatchUploadData]:
3287
+ ) -> AsyncHttpResponse[SingleUploadData]:
2539
3288
  """
2540
- Update multiple existing documents with new content and metadata.
3289
+ Replace an existing document with updated content.
2541
3290
 
2542
- Use this endpoint when you need to replace or modify several documents that are already in your knowledge base. Each file must correspond to an existing source ID, ensuring that updates are applied to the correct documents.
3291
+ This endpoint allows you to update a specific document that's already in your knowledge base. Provide the source ID of the document you want to modify, along with the new file content.
2543
3292
 
2544
- The system processes updates asynchronously, allowing you to continue working while your documents are re-indexed. Track the progress using the returned file IDs to know when updates are complete.
3293
+ The system will process your update asynchronously and re-index the document with the new content. You can monitor the progress using the returned file ID.
2545
3294
 
2546
3295
  Parameters
2547
3296
  ----------
3297
+ source_id : str
3298
+ The source ID of the document to update
3299
+
2548
3300
  tenant_id : str
2549
3301
  Unique identifier for the tenant/organization
2550
3302
 
2551
- files : typing.List[core.File]
3303
+ file : core.File
2552
3304
  See core.File for more documentation
2553
3305
 
2554
3306
  sub_tenant_id : typing.Optional[str]
2555
3307
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2556
3308
 
2557
- source_ids : typing.Optional[typing.List[str]]
2558
- List of source IDs corresponding to the files being updated
2559
-
2560
3309
  tenant_metadata : typing.Optional[str]
2561
3310
  JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
2562
3311
 
@@ -2575,23 +3324,23 @@ class AsyncRawUploadClient:
2575
3324
 
2576
3325
  Returns
2577
3326
  -------
2578
- AsyncHttpResponse[BatchUploadData]
3327
+ AsyncHttpResponse[SingleUploadData]
2579
3328
  Successful Response
2580
3329
  """
2581
3330
  _response = await self._client_wrapper.httpx_client.request(
2582
- "upload/batch_update",
3331
+ "upload/update_document",
2583
3332
  method="PATCH",
2584
3333
  params={
3334
+ "source_id": source_id,
2585
3335
  "tenant_id": tenant_id,
2586
3336
  "sub_tenant_id": sub_tenant_id,
2587
3337
  },
2588
3338
  data={
2589
- "source_ids": source_ids,
2590
3339
  "tenant_metadata": tenant_metadata,
2591
3340
  "document_metadata": document_metadata,
2592
3341
  },
2593
3342
  files={
2594
- "files": files,
3343
+ "file": file,
2595
3344
  },
2596
3345
  request_options=request_options,
2597
3346
  omit=OMIT,
@@ -2600,9 +3349,9 @@ class AsyncRawUploadClient:
2600
3349
  try:
2601
3350
  if 200 <= _response.status_code < 300:
2602
3351
  _data = typing.cast(
2603
- BatchUploadData,
3352
+ SingleUploadData,
2604
3353
  parse_obj_as(
2605
- type_=BatchUploadData, # type: ignore
3354
+ type_=SingleUploadData, # type: ignore
2606
3355
  object_=_response.json(),
2607
3356
  ),
2608
3357
  )
@@ -2689,84 +3438,61 @@ class AsyncRawUploadClient:
2689
3438
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2690
3439
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2691
3440
 
2692
- async def upload_document(
3441
+ async def upload_app_sources(
2693
3442
  self,
2694
3443
  *,
2695
3444
  tenant_id: str,
2696
- file: core.File,
3445
+ request: typing.Sequence[SourceModel],
2697
3446
  sub_tenant_id: typing.Optional[str] = None,
2698
- file_id: typing.Optional[str] = OMIT,
2699
- tenant_metadata: typing.Optional[str] = OMIT,
2700
- document_metadata: typing.Optional[str] = OMIT,
2701
3447
  request_options: typing.Optional[RequestOptions] = None,
2702
- ) -> AsyncHttpResponse[SingleUploadData]:
3448
+ ) -> AsyncHttpResponse[AppSourcesUploadData]:
2703
3449
  """
2704
- Upload a single document for processing and indexing into your knowledge base.
3450
+ Upload structured data from applications or APIs for indexing.
2705
3451
 
2706
- This endpoint accepts documents in various formats and processes them for search and retrieval. You can include custom metadata to help organize and categorize your content.
3452
+ This endpoint is designed for importing data from applications. If you are specifically using Cortex to provide search to an application, you should prefer this endpoint. It accepts structured source objects and allows you to clearly define contents of attachments
2707
3453
 
2708
- The system extracts text content, processes it asynchronously, and makes it available for search queries. You can track the processing status using the returned file ID.
3454
+ The system processes each source asynchronously and makes the content available for search and retrieval. Use this when you need to integrate search and indexing from data in your applications into your knowledge base.
2709
3455
 
2710
3456
  Parameters
2711
3457
  ----------
2712
3458
  tenant_id : str
2713
3459
  Unique identifier for the tenant/organization
2714
3460
 
2715
- file : core.File
2716
- See core.File for more documentation
3461
+ request : typing.Sequence[SourceModel]
2717
3462
 
2718
3463
  sub_tenant_id : typing.Optional[str]
2719
3464
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2720
3465
 
2721
- file_id : typing.Optional[str]
2722
- Optional file ID for the uploaded content. If not provided, will be generated automatically.
2723
-
2724
- tenant_metadata : typing.Optional[str]
2725
- JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
2726
-
2727
- Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
2728
-
2729
-
2730
- document_metadata : typing.Optional[str]
2731
- JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
2732
-
2733
- Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
2734
-
2735
-
2736
-
2737
3466
  request_options : typing.Optional[RequestOptions]
2738
3467
  Request-specific configuration.
2739
3468
 
2740
3469
  Returns
2741
3470
  -------
2742
- AsyncHttpResponse[SingleUploadData]
3471
+ AsyncHttpResponse[AppSourcesUploadData]
2743
3472
  Successful Response
2744
3473
  """
2745
3474
  _response = await self._client_wrapper.httpx_client.request(
2746
- "upload/upload_document",
3475
+ "upload/upload_app_sources",
2747
3476
  method="POST",
2748
3477
  params={
2749
3478
  "tenant_id": tenant_id,
2750
3479
  "sub_tenant_id": sub_tenant_id,
2751
3480
  },
2752
- data={
2753
- "file_id": file_id,
2754
- "tenant_metadata": tenant_metadata,
2755
- "document_metadata": document_metadata,
2756
- },
2757
- files={
2758
- "file": file,
3481
+ json=convert_and_respect_annotation_metadata(
3482
+ object_=request, annotation=typing.Sequence[SourceModel], direction="write"
3483
+ ),
3484
+ headers={
3485
+ "content-type": "application/json",
2759
3486
  },
2760
3487
  request_options=request_options,
2761
3488
  omit=OMIT,
2762
- force_multipart=True,
2763
3489
  )
2764
3490
  try:
2765
3491
  if 200 <= _response.status_code < 300:
2766
3492
  _data = typing.cast(
2767
- SingleUploadData,
3493
+ AppSourcesUploadData,
2768
3494
  parse_obj_as(
2769
- type_=SingleUploadData, # type: ignore
3495
+ type_=AppSourcesUploadData, # type: ignore
2770
3496
  object_=_response.json(),
2771
3497
  ),
2772
3498
  )
@@ -2853,51 +3579,49 @@ class AsyncRawUploadClient:
2853
3579
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
2854
3580
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
2855
3581
 
2856
- async def update_document(
3582
+ async def upload_markdown(
2857
3583
  self,
2858
3584
  *,
2859
- source_id: str,
2860
3585
  tenant_id: str,
2861
- file: core.File,
3586
+ content: str,
2862
3587
  sub_tenant_id: typing.Optional[str] = None,
2863
- tenant_metadata: typing.Optional[str] = OMIT,
2864
- document_metadata: typing.Optional[str] = OMIT,
3588
+ file_id: typing.Optional[str] = OMIT,
3589
+ tenant_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3590
+ document_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
2865
3591
  request_options: typing.Optional[RequestOptions] = None,
2866
3592
  ) -> AsyncHttpResponse[SingleUploadData]:
2867
3593
  """
2868
- Replace an existing document with updated content.
3594
+ Upload text or markdown content directly for processing.
2869
3595
 
2870
- This endpoint allows you to update a specific document that's already in your knowledge base. Provide the source ID of the document you want to modify, along with the new file content.
3596
+ This endpoint accepts plain text or markdown-formatted content that you want to add to your knowledge base. It's perfect for notes, documentation, articles, or any text-based content you want to make searchable.
2871
3597
 
2872
- The system will process your update asynchronously and re-index the document with the new content. You can monitor the progress using the returned file ID.
3598
+ You can include custom metadata to help organize and categorize your content. You can track the processing status using the returned file ID.
2873
3599
 
2874
3600
  Parameters
2875
3601
  ----------
2876
- source_id : str
2877
- The source ID of the document to update
2878
-
2879
3602
  tenant_id : str
2880
3603
  Unique identifier for the tenant/organization
2881
3604
 
2882
- file : core.File
2883
- See core.File for more documentation
3605
+ content : str
3606
+ The text or markdown content to upload
2884
3607
 
2885
3608
  sub_tenant_id : typing.Optional[str]
2886
3609
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
2887
3610
 
2888
- tenant_metadata : typing.Optional[str]
3611
+ file_id : typing.Optional[str]
3612
+ Optional file ID for the uploaded content. If not provided, will be generated automatically.
3613
+
3614
+ tenant_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
2889
3615
  JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
2890
3616
 
2891
3617
  Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
2892
3618
 
2893
-
2894
- document_metadata : typing.Optional[str]
3619
+ document_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
2895
3620
  JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
2896
3621
 
2897
3622
  Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
2898
3623
 
2899
3624
 
2900
-
2901
3625
  request_options : typing.Optional[RequestOptions]
2902
3626
  Request-specific configuration.
2903
3627
 
@@ -2907,23 +3631,23 @@ class AsyncRawUploadClient:
2907
3631
  Successful Response
2908
3632
  """
2909
3633
  _response = await self._client_wrapper.httpx_client.request(
2910
- "upload/update_document",
2911
- method="PATCH",
3634
+ "upload/upload_markdown",
3635
+ method="POST",
2912
3636
  params={
2913
- "source_id": source_id,
2914
3637
  "tenant_id": tenant_id,
2915
3638
  "sub_tenant_id": sub_tenant_id,
2916
3639
  },
2917
- data={
3640
+ json={
3641
+ "content": content,
3642
+ "file_id": file_id,
2918
3643
  "tenant_metadata": tenant_metadata,
2919
3644
  "document_metadata": document_metadata,
2920
3645
  },
2921
- files={
2922
- "file": file,
3646
+ headers={
3647
+ "content-type": "application/json",
2923
3648
  },
2924
3649
  request_options=request_options,
2925
3650
  omit=OMIT,
2926
- force_multipart=True,
2927
3651
  )
2928
3652
  try:
2929
3653
  if 200 <= _response.status_code < 300:
@@ -3017,49 +3741,70 @@ class AsyncRawUploadClient:
3017
3741
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3018
3742
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3019
3743
 
3020
- async def upload_app_sources(
3744
+ async def upload_text(
3021
3745
  self,
3022
3746
  *,
3023
3747
  tenant_id: str,
3024
- request: typing.Sequence[SourceModel],
3748
+ content: str,
3025
3749
  sub_tenant_id: typing.Optional[str] = None,
3750
+ file_id: typing.Optional[str] = OMIT,
3751
+ tenant_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3752
+ document_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3026
3753
  request_options: typing.Optional[RequestOptions] = None,
3027
- ) -> AsyncHttpResponse[AppSourcesUploadData]:
3754
+ ) -> AsyncHttpResponse[SingleUploadData]:
3028
3755
  """
3029
- Upload structured data from applications or APIs for indexing.
3756
+ Upload text or markdown content directly for processing.
3030
3757
 
3031
- This endpoint is designed for importing data from applications. If you are specifically using Cortex to provide search to an application, you should prefer this endpoint. It accepts structured source objects and allows you to clearly define contents of attachments
3758
+ This endpoint accepts plain text or markdown-formatted content that you want to add to your knowledge base. It's perfect for notes, documentation, articles, or any text-based content you want to make searchable.
3032
3759
 
3033
- The system processes each source asynchronously and makes the content available for search and retrieval. Use this when you need to integrate search and indexing from data in your applications into your knowledge base.
3760
+ You can include custom metadata to help organize and categorize your content. You can track the processing status using the returned file ID.
3034
3761
 
3035
3762
  Parameters
3036
3763
  ----------
3037
3764
  tenant_id : str
3038
3765
  Unique identifier for the tenant/organization
3039
3766
 
3040
- request : typing.Sequence[SourceModel]
3767
+ content : str
3768
+ The text or markdown content to upload
3041
3769
 
3042
3770
  sub_tenant_id : typing.Optional[str]
3043
3771
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
3044
3772
 
3773
+ file_id : typing.Optional[str]
3774
+ Optional file ID for the uploaded content. If not provided, will be generated automatically.
3775
+
3776
+ tenant_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3777
+ JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
3778
+
3779
+ Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
3780
+
3781
+ document_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3782
+ JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
3783
+
3784
+ Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
3785
+
3786
+
3045
3787
  request_options : typing.Optional[RequestOptions]
3046
3788
  Request-specific configuration.
3047
3789
 
3048
3790
  Returns
3049
3791
  -------
3050
- AsyncHttpResponse[AppSourcesUploadData]
3792
+ AsyncHttpResponse[SingleUploadData]
3051
3793
  Successful Response
3052
3794
  """
3053
3795
  _response = await self._client_wrapper.httpx_client.request(
3054
- "upload/upload_app_sources",
3796
+ "upload/upload_text",
3055
3797
  method="POST",
3056
3798
  params={
3057
3799
  "tenant_id": tenant_id,
3058
3800
  "sub_tenant_id": sub_tenant_id,
3059
3801
  },
3060
- json=convert_and_respect_annotation_metadata(
3061
- object_=request, annotation=typing.Sequence[SourceModel], direction="write"
3062
- ),
3802
+ json={
3803
+ "content": content,
3804
+ "file_id": file_id,
3805
+ "tenant_metadata": tenant_metadata,
3806
+ "document_metadata": document_metadata,
3807
+ },
3063
3808
  headers={
3064
3809
  "content-type": "application/json",
3065
3810
  },
@@ -3069,9 +3814,9 @@ class AsyncRawUploadClient:
3069
3814
  try:
3070
3815
  if 200 <= _response.status_code < 300:
3071
3816
  _data = typing.cast(
3072
- AppSourcesUploadData,
3817
+ SingleUploadData,
3073
3818
  parse_obj_as(
3074
- type_=AppSourcesUploadData, # type: ignore
3819
+ type_=SingleUploadData, # type: ignore
3075
3820
  object_=_response.json(),
3076
3821
  ),
3077
3822
  )
@@ -3158,9 +3903,10 @@ class AsyncRawUploadClient:
3158
3903
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3159
3904
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3160
3905
 
3161
- async def upload_markdown(
3906
+ async def update_markdown(
3162
3907
  self,
3163
3908
  *,
3909
+ source_id: str,
3164
3910
  tenant_id: str,
3165
3911
  content: str,
3166
3912
  sub_tenant_id: typing.Optional[str] = None,
@@ -3170,14 +3916,17 @@ class AsyncRawUploadClient:
3170
3916
  request_options: typing.Optional[RequestOptions] = None,
3171
3917
  ) -> AsyncHttpResponse[SingleUploadData]:
3172
3918
  """
3173
- Upload text or markdown content directly for processing.
3919
+ Update existing text or markdown content with new information.
3174
3920
 
3175
- This endpoint accepts plain text or markdown-formatted content that you want to add to your knowledge base. It's perfect for notes, documentation, articles, or any text-based content you want to make searchable.
3921
+ This endpoint allows you to modify text or markdown content that's already in your knowledge base. Provide the source ID of the content you want to update, along with the new text.
3176
3922
 
3177
- You can include custom metadata to help organize and categorize your content. You can track the processing status using the returned file ID.
3923
+ The system will reprocess and re-index the updated content asynchronously. Use this when you need to correct information, add details, or refresh existing documentation.
3178
3924
 
3179
3925
  Parameters
3180
3926
  ----------
3927
+ source_id : str
3928
+ The source ID of the document to update
3929
+
3181
3930
  tenant_id : str
3182
3931
  Unique identifier for the tenant/organization
3183
3932
 
@@ -3210,9 +3959,10 @@ class AsyncRawUploadClient:
3210
3959
  Successful Response
3211
3960
  """
3212
3961
  _response = await self._client_wrapper.httpx_client.request(
3213
- "upload/upload_markdown",
3214
- method="POST",
3962
+ "upload/update_markdown",
3963
+ method="PATCH",
3215
3964
  params={
3965
+ "source_id": source_id,
3216
3966
  "tenant_id": tenant_id,
3217
3967
  "sub_tenant_id": sub_tenant_id,
3218
3968
  },
@@ -3320,9 +4070,10 @@ class AsyncRawUploadClient:
3320
4070
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3321
4071
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3322
4072
 
3323
- async def upload_text(
4073
+ async def update_text(
3324
4074
  self,
3325
4075
  *,
4076
+ source_id: str,
3326
4077
  tenant_id: str,
3327
4078
  content: str,
3328
4079
  sub_tenant_id: typing.Optional[str] = None,
@@ -3332,14 +4083,17 @@ class AsyncRawUploadClient:
3332
4083
  request_options: typing.Optional[RequestOptions] = None,
3333
4084
  ) -> AsyncHttpResponse[SingleUploadData]:
3334
4085
  """
3335
- Upload text or markdown content directly for processing.
4086
+ Update existing text or markdown content with new information.
3336
4087
 
3337
- This endpoint accepts plain text or markdown-formatted content that you want to add to your knowledge base. It's perfect for notes, documentation, articles, or any text-based content you want to make searchable.
4088
+ This endpoint allows you to modify text or markdown content that's already in your knowledge base. Provide the source ID of the content you want to update, along with the new text.
3338
4089
 
3339
- You can include custom metadata to help organize and categorize your content. You can track the processing status using the returned file ID.
4090
+ The system will reprocess and re-index the updated content asynchronously. Use this when you need to correct information, add details, or refresh existing documentation.
3340
4091
 
3341
4092
  Parameters
3342
4093
  ----------
4094
+ source_id : str
4095
+ The source ID of the document to update
4096
+
3343
4097
  tenant_id : str
3344
4098
  Unique identifier for the tenant/organization
3345
4099
 
@@ -3372,9 +4126,10 @@ class AsyncRawUploadClient:
3372
4126
  Successful Response
3373
4127
  """
3374
4128
  _response = await self._client_wrapper.httpx_client.request(
3375
- "upload/upload_text",
3376
- method="POST",
4129
+ "upload/update_text",
4130
+ method="PATCH",
3377
4131
  params={
4132
+ "source_id": source_id,
3378
4133
  "tenant_id": tenant_id,
3379
4134
  "sub_tenant_id": sub_tenant_id,
3380
4135
  },
@@ -3482,75 +4237,47 @@ class AsyncRawUploadClient:
3482
4237
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3483
4238
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3484
4239
 
3485
- async def update_markdown(
4240
+ async def batch_upload_markdown(
3486
4241
  self,
3487
4242
  *,
3488
- source_id: str,
3489
4243
  tenant_id: str,
3490
- content: str,
4244
+ request: typing.Sequence[MarkdownUploadRequest],
3491
4245
  sub_tenant_id: typing.Optional[str] = None,
3492
- file_id: typing.Optional[str] = OMIT,
3493
- tenant_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3494
- document_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3495
4246
  request_options: typing.Optional[RequestOptions] = None,
3496
- ) -> AsyncHttpResponse[SingleUploadData]:
4247
+ ) -> AsyncHttpResponse[BatchUploadData]:
3497
4248
  """
3498
- Update existing text or markdown content with new information.
3499
-
3500
- This endpoint allows you to modify text or markdown content that's already in your knowledge base. Provide the source ID of the content you want to update, along with the new text.
4249
+ Upload multiple markdown/text documents simultaneously for efficient bulk processing.
3501
4250
 
3502
- The system will reprocess and re-index the updated content asynchronously. Use this when you need to correct information, add details, or refresh existing documentation.
4251
+ This endpoint allows you to upload several markdown or text contents at once. Each content item gets processed asynchronously, and you can track the progress using their returned file IDs.
3503
4252
 
3504
4253
  Parameters
3505
4254
  ----------
3506
- source_id : str
3507
- The source ID of the document to update
3508
-
3509
4255
  tenant_id : str
3510
4256
  Unique identifier for the tenant/organization
3511
4257
 
3512
- content : str
3513
- The text or markdown content to upload
4258
+ request : typing.Sequence[MarkdownUploadRequest]
3514
4259
 
3515
4260
  sub_tenant_id : typing.Optional[str]
3516
4261
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
3517
4262
 
3518
- file_id : typing.Optional[str]
3519
- Optional file ID for the uploaded content. If not provided, will be generated automatically.
3520
-
3521
- tenant_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3522
- JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
3523
-
3524
- Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
3525
-
3526
- document_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3527
- JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
3528
-
3529
- Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
3530
-
3531
-
3532
4263
  request_options : typing.Optional[RequestOptions]
3533
4264
  Request-specific configuration.
3534
4265
 
3535
4266
  Returns
3536
4267
  -------
3537
- AsyncHttpResponse[SingleUploadData]
4268
+ AsyncHttpResponse[BatchUploadData]
3538
4269
  Successful Response
3539
4270
  """
3540
4271
  _response = await self._client_wrapper.httpx_client.request(
3541
- "upload/update_markdown",
3542
- method="PATCH",
4272
+ "upload/batch_upload_markdown",
4273
+ method="POST",
3543
4274
  params={
3544
- "source_id": source_id,
3545
4275
  "tenant_id": tenant_id,
3546
4276
  "sub_tenant_id": sub_tenant_id,
3547
4277
  },
3548
- json={
3549
- "content": content,
3550
- "file_id": file_id,
3551
- "tenant_metadata": tenant_metadata,
3552
- "document_metadata": document_metadata,
3553
- },
4278
+ json=convert_and_respect_annotation_metadata(
4279
+ object_=request, annotation=typing.Sequence[MarkdownUploadRequest], direction="write"
4280
+ ),
3554
4281
  headers={
3555
4282
  "content-type": "application/json",
3556
4283
  },
@@ -3560,9 +4287,9 @@ class AsyncRawUploadClient:
3560
4287
  try:
3561
4288
  if 200 <= _response.status_code < 300:
3562
4289
  _data = typing.cast(
3563
- SingleUploadData,
4290
+ BatchUploadData,
3564
4291
  parse_obj_as(
3565
- type_=SingleUploadData, # type: ignore
4292
+ type_=BatchUploadData, # type: ignore
3566
4293
  object_=_response.json(),
3567
4294
  ),
3568
4295
  )
@@ -3649,75 +4376,47 @@ class AsyncRawUploadClient:
3649
4376
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
3650
4377
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
3651
4378
 
3652
- async def update_text(
4379
+ async def batch_upload_text(
3653
4380
  self,
3654
4381
  *,
3655
- source_id: str,
3656
4382
  tenant_id: str,
3657
- content: str,
4383
+ request: typing.Sequence[MarkdownUploadRequest],
3658
4384
  sub_tenant_id: typing.Optional[str] = None,
3659
- file_id: typing.Optional[str] = OMIT,
3660
- tenant_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3661
- document_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
3662
4385
  request_options: typing.Optional[RequestOptions] = None,
3663
- ) -> AsyncHttpResponse[SingleUploadData]:
4386
+ ) -> AsyncHttpResponse[BatchUploadData]:
3664
4387
  """
3665
- Update existing text or markdown content with new information.
3666
-
3667
- This endpoint allows you to modify text or markdown content that's already in your knowledge base. Provide the source ID of the content you want to update, along with the new text.
4388
+ Upload multiple markdown/text documents simultaneously for efficient bulk processing.
3668
4389
 
3669
- The system will reprocess and re-index the updated content asynchronously. Use this when you need to correct information, add details, or refresh existing documentation.
4390
+ This endpoint allows you to upload several markdown or text contents at once. Each content item gets processed asynchronously, and you can track the progress using their returned file IDs.
3670
4391
 
3671
4392
  Parameters
3672
4393
  ----------
3673
- source_id : str
3674
- The source ID of the document to update
3675
-
3676
4394
  tenant_id : str
3677
4395
  Unique identifier for the tenant/organization
3678
4396
 
3679
- content : str
3680
- The text or markdown content to upload
4397
+ request : typing.Sequence[MarkdownUploadRequest]
3681
4398
 
3682
4399
  sub_tenant_id : typing.Optional[str]
3683
4400
  Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
3684
4401
 
3685
- file_id : typing.Optional[str]
3686
- Optional file ID for the uploaded content. If not provided, will be generated automatically.
3687
-
3688
- tenant_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3689
- JSON string containing tenant-level document metadata (e.g., department, compliance_tag)
3690
-
3691
- Example: > "{"department":"Finance","compliance_tag":"GDPR"}"
3692
-
3693
- document_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
3694
- JSON string containing document-specific metadata (e.g., title, author, file_id). If file_id is not provided, the system will generate an ID automatically.
3695
-
3696
- Example: > "{"title":"Q1 Report.pdf","author":"Alice Smith","file_id":"custom_file_123"}"
3697
-
3698
-
3699
4402
  request_options : typing.Optional[RequestOptions]
3700
4403
  Request-specific configuration.
3701
4404
 
3702
4405
  Returns
3703
4406
  -------
3704
- AsyncHttpResponse[SingleUploadData]
4407
+ AsyncHttpResponse[BatchUploadData]
3705
4408
  Successful Response
3706
4409
  """
3707
4410
  _response = await self._client_wrapper.httpx_client.request(
3708
- "upload/update_text",
3709
- method="PATCH",
4411
+ "upload/batch_upload_text",
4412
+ method="POST",
3710
4413
  params={
3711
- "source_id": source_id,
3712
4414
  "tenant_id": tenant_id,
3713
4415
  "sub_tenant_id": sub_tenant_id,
3714
4416
  },
3715
- json={
3716
- "content": content,
3717
- "file_id": file_id,
3718
- "tenant_metadata": tenant_metadata,
3719
- "document_metadata": document_metadata,
3720
- },
4417
+ json=convert_and_respect_annotation_metadata(
4418
+ object_=request, annotation=typing.Sequence[MarkdownUploadRequest], direction="write"
4419
+ ),
3721
4420
  headers={
3722
4421
  "content-type": "application/json",
3723
4422
  },
@@ -3727,9 +4426,9 @@ class AsyncRawUploadClient:
3727
4426
  try:
3728
4427
  if 200 <= _response.status_code < 300:
3729
4428
  _data = typing.cast(
3730
- SingleUploadData,
4429
+ BatchUploadData,
3731
4430
  parse_obj_as(
3732
- type_=SingleUploadData, # type: ignore
4431
+ type_=BatchUploadData, # type: ignore
3733
4432
  object_=_response.json(),
3734
4433
  ),
3735
4434
  )
@@ -4397,6 +5096,147 @@ class AsyncRawUploadClient:
4397
5096
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
4398
5097
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
4399
5098
 
5099
+ async def batch_scrape_webpage(
5100
+ self,
5101
+ *,
5102
+ tenant_id: str,
5103
+ request: typing.Sequence[WebpageScrapeRequest],
5104
+ sub_tenant_id: typing.Optional[str] = None,
5105
+ request_options: typing.Optional[RequestOptions] = None,
5106
+ ) -> AsyncHttpResponse[BatchUploadData]:
5107
+ """
5108
+ Extract and index content from multiple web pages simultaneously.
5109
+
5110
+ This endpoint initiates web scraping for multiple URLs at once, extracting the main content, text, and structure from each webpage. It's perfect for capturing multiple articles, documentation pages, or any web content you want to include in your knowledge base.
5111
+
5112
+ The system processes all webpage content asynchronously, cleaning and structuring the information for optimal search and retrieval.
5113
+
5114
+ Parameters
5115
+ ----------
5116
+ tenant_id : str
5117
+ Unique identifier for the tenant/organization
5118
+
5119
+ request : typing.Sequence[WebpageScrapeRequest]
5120
+
5121
+ sub_tenant_id : typing.Optional[str]
5122
+ Optional sub-tenant identifier used to organize data within a tenant. If omitted, the default sub-tenant created during tenant setup will be used.
5123
+
5124
+ request_options : typing.Optional[RequestOptions]
5125
+ Request-specific configuration.
5126
+
5127
+ Returns
5128
+ -------
5129
+ AsyncHttpResponse[BatchUploadData]
5130
+ Successful Response
5131
+ """
5132
+ _response = await self._client_wrapper.httpx_client.request(
5133
+ "upload/batch_scrape_webpage",
5134
+ method="POST",
5135
+ params={
5136
+ "tenant_id": tenant_id,
5137
+ "sub_tenant_id": sub_tenant_id,
5138
+ },
5139
+ json=convert_and_respect_annotation_metadata(
5140
+ object_=request, annotation=typing.Sequence[WebpageScrapeRequest], direction="write"
5141
+ ),
5142
+ headers={
5143
+ "content-type": "application/json",
5144
+ },
5145
+ request_options=request_options,
5146
+ omit=OMIT,
5147
+ )
5148
+ try:
5149
+ if 200 <= _response.status_code < 300:
5150
+ _data = typing.cast(
5151
+ BatchUploadData,
5152
+ parse_obj_as(
5153
+ type_=BatchUploadData, # type: ignore
5154
+ object_=_response.json(),
5155
+ ),
5156
+ )
5157
+ return AsyncHttpResponse(response=_response, data=_data)
5158
+ if _response.status_code == 400:
5159
+ raise BadRequestError(
5160
+ headers=dict(_response.headers),
5161
+ body=typing.cast(
5162
+ ActualErrorResponse,
5163
+ parse_obj_as(
5164
+ type_=ActualErrorResponse, # type: ignore
5165
+ object_=_response.json(),
5166
+ ),
5167
+ ),
5168
+ )
5169
+ if _response.status_code == 401:
5170
+ raise UnauthorizedError(
5171
+ headers=dict(_response.headers),
5172
+ body=typing.cast(
5173
+ ActualErrorResponse,
5174
+ parse_obj_as(
5175
+ type_=ActualErrorResponse, # type: ignore
5176
+ object_=_response.json(),
5177
+ ),
5178
+ ),
5179
+ )
5180
+ if _response.status_code == 403:
5181
+ raise ForbiddenError(
5182
+ headers=dict(_response.headers),
5183
+ body=typing.cast(
5184
+ ActualErrorResponse,
5185
+ parse_obj_as(
5186
+ type_=ActualErrorResponse, # type: ignore
5187
+ object_=_response.json(),
5188
+ ),
5189
+ ),
5190
+ )
5191
+ if _response.status_code == 404:
5192
+ raise NotFoundError(
5193
+ headers=dict(_response.headers),
5194
+ body=typing.cast(
5195
+ ActualErrorResponse,
5196
+ parse_obj_as(
5197
+ type_=ActualErrorResponse, # type: ignore
5198
+ object_=_response.json(),
5199
+ ),
5200
+ ),
5201
+ )
5202
+ if _response.status_code == 422:
5203
+ raise UnprocessableEntityError(
5204
+ headers=dict(_response.headers),
5205
+ body=typing.cast(
5206
+ typing.Optional[typing.Any],
5207
+ parse_obj_as(
5208
+ type_=typing.Optional[typing.Any], # type: ignore
5209
+ object_=_response.json(),
5210
+ ),
5211
+ ),
5212
+ )
5213
+ if _response.status_code == 500:
5214
+ raise InternalServerError(
5215
+ headers=dict(_response.headers),
5216
+ body=typing.cast(
5217
+ ActualErrorResponse,
5218
+ parse_obj_as(
5219
+ type_=ActualErrorResponse, # type: ignore
5220
+ object_=_response.json(),
5221
+ ),
5222
+ ),
5223
+ )
5224
+ if _response.status_code == 503:
5225
+ raise ServiceUnavailableError(
5226
+ headers=dict(_response.headers),
5227
+ body=typing.cast(
5228
+ ActualErrorResponse,
5229
+ parse_obj_as(
5230
+ type_=ActualErrorResponse, # type: ignore
5231
+ object_=_response.json(),
5232
+ ),
5233
+ ),
5234
+ )
5235
+ _response_json = _response.json()
5236
+ except JSONDecodeError:
5237
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
5238
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
5239
+
4400
5240
  async def delete_source(
4401
5241
  self,
4402
5242
  *,