groundx 2.0.21__py3-none-any.whl → 2.0.29__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.
groundx/__init__.py CHANGED
@@ -9,6 +9,7 @@ from .types import (
9
9
  BucketUpdateResponse,
10
10
  CustomerDetail,
11
11
  CustomerResponse,
12
+ Document,
12
13
  DocumentDetail,
13
14
  DocumentListResponse,
14
15
  DocumentLocalIngestRequest,
@@ -48,8 +49,8 @@ from .types import (
48
49
  )
49
50
  from .errors import BadRequestError, UnauthorizedError
50
51
  from . import buckets, customer, documents, groups, health, search
51
- from .client import AsyncGroundX, GroundX
52
52
  from .environment import GroundXEnvironment
53
+ from .ingest import AsyncGroundX, GroundX
53
54
  from .search import SearchContentRequestId
54
55
  from .version import __version__
55
56
 
@@ -64,6 +65,7 @@ __all__ = [
64
65
  "BucketUpdateResponse",
65
66
  "CustomerDetail",
66
67
  "CustomerResponse",
68
+ "Document",
67
69
  "DocumentDetail",
68
70
  "DocumentListResponse",
69
71
  "DocumentLocalIngestRequest",
groundx/client.py CHANGED
@@ -19,7 +19,7 @@ from .customer.client import AsyncCustomerClient
19
19
  from .health.client import AsyncHealthClient
20
20
 
21
21
 
22
- class GroundX:
22
+ class GroundXBase:
23
23
  """
24
24
  Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
25
25
 
@@ -85,7 +85,7 @@ class GroundX:
85
85
  self.health = HealthClient(client_wrapper=self._client_wrapper)
86
86
 
87
87
 
88
- class AsyncGroundX:
88
+ class AsyncGroundXBase:
89
89
  """
90
90
  Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
91
91
 
@@ -16,7 +16,7 @@ class BaseClientWrapper:
16
16
  headers: typing.Dict[str, str] = {
17
17
  "X-Fern-Language": "Python",
18
18
  "X-Fern-SDK-Name": "groundx",
19
- "X-Fern-SDK-Version": "2.0.21",
19
+ "X-Fern-SDK-Version": "2.0.29",
20
20
  }
21
21
  headers["X-API-Key"] = self.api_key
22
22
  return headers
groundx/ingest.py ADDED
@@ -0,0 +1,334 @@
1
+ import aiohttp, io, json, mimetypes, requests, typing, os
2
+ from asyncio import TimeoutError
3
+ from urllib.parse import urlparse
4
+
5
+ from json.decoder import JSONDecodeError
6
+
7
+ from .client import GroundXBase, AsyncGroundXBase
8
+ from .core.api_error import ApiError
9
+ from .core.pydantic_utilities import parse_obj_as
10
+ from .core.request_options import RequestOptions
11
+ from .errors.bad_request_error import BadRequestError
12
+ from .errors.unauthorized_error import UnauthorizedError
13
+ from .types.document import Document
14
+ from .types.ingest_remote_document import IngestRemoteDocument
15
+ from .types.ingest_response import IngestResponse
16
+
17
+ # this is used as the default value for optional parameters
18
+ OMIT = typing.cast(typing.Any, ...)
19
+
20
+
21
+ DOCUMENT_TYPE_TO_MIME = {
22
+ "txt": "text/plain",
23
+ "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
24
+ "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
25
+ "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
26
+ "pdf": "application/pdf",
27
+ "png": "image/png",
28
+ "jpg": "image/jpeg",
29
+ "csv": "text/csv",
30
+ "tsv": "text/tab-separated-values",
31
+ "json": "application/json",
32
+ }
33
+ MIME_TO_DOCUMENT_TYPE = {v: k for k, v in DOCUMENT_TYPE_TO_MIME.items()}
34
+
35
+
36
+ def prep_documents(
37
+ documents: typing.Sequence[Document],
38
+ ) -> typing.Tuple[
39
+ typing.List[IngestRemoteDocument],
40
+ typing.List[
41
+ typing.Tuple[str, typing.Tuple[typing.Union[str, None], typing.BinaryIO, str]]
42
+ ],
43
+ ]:
44
+ """
45
+ Process documents and separate them into remote and local documents.
46
+ """
47
+ if not documents:
48
+ raise ValueError("No documents provided for ingestion.")
49
+
50
+ def is_valid_local_path(path: str) -> bool:
51
+ expanded_path = os.path.expanduser(path)
52
+ return os.path.exists(expanded_path)
53
+
54
+ def is_valid_url(path: str) -> bool:
55
+ try:
56
+ result = urlparse(path)
57
+ return all([result.scheme, result.netloc])
58
+ except ValueError:
59
+ return False
60
+
61
+ idx = 0
62
+ remote_documents: typing.List[IngestRemoteDocument] = []
63
+ local_documents: typing.List[
64
+ typing.Tuple[str, typing.Tuple[typing.Union[str, None], typing.BinaryIO, str]]
65
+ ] = []
66
+
67
+ for document in documents:
68
+ if not hasattr(document, "file_path"):
69
+ raise ValueError("Each document must have a 'file_path' attribute.")
70
+
71
+ if is_valid_url(document.file_path):
72
+ remote_document = IngestRemoteDocument(
73
+ bucket_id=document.bucket_id,
74
+ file_name=document.file_name,
75
+ file_type=document.file_type,
76
+ search_data=document.search_data,
77
+ source_url=document.file_path,
78
+ )
79
+ remote_documents.append(remote_document)
80
+ elif is_valid_local_path(document.file_path):
81
+ expanded_path = os.path.expanduser(document.file_path)
82
+ file_name = os.path.basename(expanded_path)
83
+ mime_type = mimetypes.guess_type(file_name)[0] or "application/octet-stream"
84
+ file_type = MIME_TO_DOCUMENT_TYPE.get(mime_type, None)
85
+ if document.file_type:
86
+ file_type = document.file_type
87
+ mime_type = DOCUMENT_TYPE_TO_MIME.get(
88
+ document.file_type, "application/octet-stream"
89
+ )
90
+
91
+ if document.file_name:
92
+ file_name = document.file_name
93
+
94
+ try:
95
+ local_documents.append(
96
+ (
97
+ "blob",
98
+ (
99
+ file_name,
100
+ open(expanded_path, "rb"),
101
+ mime_type,
102
+ ),
103
+ )
104
+ )
105
+ except Exception as e:
106
+ raise ValueError(f"Error reading file {expanded_path}: {e}")
107
+
108
+ metadata = {
109
+ "bucketId": document.bucket_id,
110
+ "fileName": file_name,
111
+ "fileType": file_type,
112
+ }
113
+ if document.search_data:
114
+ metadata["searchData"] = document.search_data
115
+
116
+ local_documents.append(
117
+ (
118
+ "metadata",
119
+ (
120
+ f"data.json",
121
+ io.BytesIO(json.dumps(metadata).encode("utf-8")),
122
+ "application/json",
123
+ ),
124
+ )
125
+ )
126
+ idx += 1
127
+ else:
128
+ raise ValueError(f"Invalid file path: {document.file_path}")
129
+
130
+ return remote_documents, local_documents
131
+
132
+
133
+ class GroundX(GroundXBase):
134
+ def ingest(
135
+ self,
136
+ *,
137
+ documents: typing.Sequence[Document],
138
+ request_options: typing.Optional[RequestOptions] = None,
139
+ ) -> IngestResponse:
140
+ """
141
+ Ingest local or hosted documents into a GroundX bucket.
142
+
143
+ Parameters
144
+ ----------
145
+ documents : typing.Sequence[Document]
146
+
147
+ request_options : typing.Optional[RequestOptions]
148
+ Request-specific configuration.
149
+
150
+ Returns
151
+ -------
152
+ IngestResponse
153
+ Documents successfully uploaded
154
+
155
+ Examples
156
+ --------
157
+ from groundx import Document, GroundX
158
+
159
+ client = GroundX(
160
+ api_key="YOUR_API_KEY",
161
+ )
162
+
163
+ client.ingest(
164
+ documents=[
165
+ Document(
166
+ bucket_id=1234,
167
+ file_name="my_file1.txt",
168
+ file_path="https://my.source.url.com/file1.txt",
169
+ file_type="txt",
170
+ )
171
+ ],
172
+ )
173
+ """
174
+ remote_documents, local_documents = prep_documents(documents)
175
+
176
+ if local_documents and remote_documents:
177
+ raise ValueError("Documents must all be either local or remote, not a mix.")
178
+
179
+ if len(remote_documents) > 0:
180
+ return self.documents.ingest_remote(
181
+ documents=remote_documents,
182
+ request_options=request_options,
183
+ )
184
+
185
+ timeout = self._client_wrapper.get_timeout()
186
+ headers = self._client_wrapper.get_headers()
187
+ base_url = self._client_wrapper.get_base_url().rstrip("/")
188
+ follow_redirects = getattr(
189
+ self._client_wrapper.httpx_client, "follow_redirects", True
190
+ )
191
+
192
+ url = f"{base_url}/v1/ingest/documents/local"
193
+ _response = requests.post(
194
+ url,
195
+ files=local_documents,
196
+ headers=headers,
197
+ timeout=timeout,
198
+ allow_redirects=follow_redirects,
199
+ )
200
+
201
+ try:
202
+ if 200 <= _response.status_code < 300:
203
+ return typing.cast(
204
+ IngestResponse,
205
+ parse_obj_as(
206
+ type_=IngestResponse, # type: ignore
207
+ object_=_response.json(),
208
+ ),
209
+ )
210
+ if _response.status_code == 400:
211
+ raise BadRequestError(
212
+ typing.cast(
213
+ typing.Optional[typing.Any],
214
+ parse_obj_as(
215
+ type_=typing.Optional[typing.Any], # type: ignore
216
+ object_=_response.json(),
217
+ ),
218
+ )
219
+ )
220
+ if _response.status_code == 401:
221
+ raise UnauthorizedError(
222
+ typing.cast(
223
+ typing.Optional[typing.Any],
224
+ parse_obj_as(
225
+ type_=typing.Optional[typing.Any], # type: ignore
226
+ object_=_response.json(),
227
+ ),
228
+ )
229
+ )
230
+ _response_json = _response.json()
231
+ except JSONDecodeError:
232
+ raise ApiError(status_code=_response.status_code, body=_response.text)
233
+
234
+ raise ApiError(status_code=_response.status_code, body=_response_json)
235
+
236
+
237
+ class AsyncGroundX(AsyncGroundXBase):
238
+ async def ingest(
239
+ self,
240
+ *,
241
+ documents: typing.Sequence[Document],
242
+ request_options: typing.Optional[RequestOptions] = None,
243
+ ) -> IngestResponse:
244
+ """
245
+ Ingest local or hosted documents into a GroundX bucket.
246
+
247
+ Parameters
248
+ ----------
249
+ documents : typing.Sequence[Document]
250
+
251
+ request_options : typing.Optional[RequestOptions]
252
+ Request-specific configuration.
253
+
254
+ Returns
255
+ -------
256
+ IngestResponse
257
+ Documents successfully uploaded
258
+
259
+ Examples
260
+ --------
261
+ import asyncio
262
+
263
+ from groundx import AsyncGroundX, Document
264
+
265
+ client = AsyncGroundX(
266
+ api_key="YOUR_API_KEY",
267
+ )
268
+
269
+ async def main() -> None:
270
+ await client.ingest(
271
+ documents=[
272
+ Document(
273
+ bucket_id=1234,
274
+ file_name="my_file1.txt",
275
+ file_path="https://my.source.url.com/file1.txt",
276
+ file_type="txt",
277
+ )
278
+ ],
279
+ )
280
+
281
+ asyncio.run(main())
282
+ """
283
+ remote_documents, local_documents = prep_documents(documents)
284
+
285
+ if local_documents and remote_documents:
286
+ raise ValueError("Documents must all be either local or remote, not a mix.")
287
+
288
+ if len(remote_documents) > 0:
289
+ return await self.documents.ingest_remote(
290
+ documents=remote_documents,
291
+ request_options=request_options,
292
+ )
293
+
294
+ timeout = self._client_wrapper.get_timeout()
295
+ headers = self._client_wrapper.get_headers()
296
+ base_url = self._client_wrapper.get_base_url().rstrip("/")
297
+
298
+ url = f"{base_url}/v1/ingest/documents/local"
299
+
300
+ try:
301
+ async with aiohttp.ClientSession() as session:
302
+ data = aiohttp.FormData()
303
+ for field_name, (file_name, file_obj, content_type) in local_documents:
304
+ data.add_field(
305
+ name=field_name,
306
+ value=file_obj,
307
+ filename=file_name,
308
+ content_type=content_type,
309
+ )
310
+
311
+ async with session.post(
312
+ url, data=data, headers=headers, timeout=timeout
313
+ ) as response:
314
+ if 200 <= response.status < 300:
315
+ response_data = await response.json()
316
+ return typing.cast(
317
+ IngestResponse,
318
+ parse_obj_as(
319
+ type_=IngestResponse, # type: ignore
320
+ object_=response_data,
321
+ ),
322
+ )
323
+ if response.status == 400:
324
+ raise BadRequestError(await response.json())
325
+ if response.status == 401:
326
+ raise UnauthorizedError(await response.json())
327
+
328
+ raise ApiError(
329
+ status_code=response.status, body=await response.text()
330
+ )
331
+ except TimeoutError:
332
+ raise ApiError(status_code=408, body="Request timed out")
333
+ except aiohttp.ClientError as e:
334
+ raise ApiError(status_code=500, body=str(e))
groundx/types/__init__.py CHANGED
@@ -8,6 +8,7 @@ from .bucket_update_detail import BucketUpdateDetail
8
8
  from .bucket_update_response import BucketUpdateResponse
9
9
  from .customer_detail import CustomerDetail
10
10
  from .customer_response import CustomerResponse
11
+ from .document import Document
11
12
  from .document_detail import DocumentDetail
12
13
  from .document_list_response import DocumentListResponse
13
14
  from .document_local_ingest_request import DocumentLocalIngestRequest
@@ -54,6 +55,7 @@ __all__ = [
54
55
  "BucketUpdateResponse",
55
56
  "CustomerDetail",
56
57
  "CustomerResponse",
58
+ "Document",
57
59
  "DocumentDetail",
58
60
  "DocumentListResponse",
59
61
  "DocumentLocalIngestRequest",
@@ -0,0 +1,45 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
5
+ from ..core.serialization import FieldMetadata
6
+ import pydantic
7
+ import typing
8
+ from .document_type import DocumentType
9
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
10
+
11
+
12
+ class Document(UniversalBaseModel):
13
+ bucket_id: typing_extensions.Annotated[int, FieldMetadata(alias="bucketId")] = pydantic.Field()
14
+ """
15
+ The bucketId of the bucket which this file will be ingested into.
16
+ """
17
+
18
+ file_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="fileName")] = pydantic.Field(
19
+ default=None
20
+ )
21
+ """
22
+ The name of the file being ingested.
23
+ """
24
+
25
+ file_path: typing_extensions.Annotated[str, FieldMetadata(alias="filePath")] = pydantic.Field()
26
+ """
27
+ The local file path or remote URL of the document being ingested by GroundX.
28
+ """
29
+
30
+ file_type: typing_extensions.Annotated[typing.Optional[DocumentType], FieldMetadata(alias="fileType")] = None
31
+ search_data: typing_extensions.Annotated[
32
+ typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]], FieldMetadata(alias="searchData")
33
+ ] = pydantic.Field(default=None)
34
+ """
35
+ Custom metadata which can be used to influence GroundX's search functionality. This data can be used to further hone GroundX search.
36
+ """
37
+
38
+ if IS_PYDANTIC_V2:
39
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
40
+ else:
41
+
42
+ class Config:
43
+ frozen = True
44
+ smart_union = True
45
+ extra = pydantic.Extra.allow
@@ -14,7 +14,7 @@ class IngestLocalDocumentMetadata(UniversalBaseModel):
14
14
  default=None
15
15
  )
16
16
  """
17
- The bucketId of the bucket which this local file will be ingested to.
17
+ The bucketId of the bucket which this local file will be ingested into.
18
18
  """
19
19
 
20
20
  file_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="fileName")] = pydantic.Field(
@@ -12,7 +12,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2
12
12
  class IngestRemoteDocument(UniversalBaseModel):
13
13
  bucket_id: typing_extensions.Annotated[int, FieldMetadata(alias="bucketId")] = pydantic.Field()
14
14
  """
15
- the bucketId of the bucket which this remote file will be ingested to.
15
+ The bucketId of the bucket which this remote file will be ingested into.
16
16
  """
17
17
 
18
18
  file_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="fileName")] = pydantic.Field(
@@ -11,7 +11,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2
11
11
  class WebsiteSource(UniversalBaseModel):
12
12
  bucket_id: typing_extensions.Annotated[int, FieldMetadata(alias="bucketId")] = pydantic.Field()
13
13
  """
14
- the bucketId of the bucket which this website will be ingested to.
14
+ The bucketId of the bucket which this website will be ingested into.
15
15
  """
16
16
 
17
17
  cap: typing.Optional[int] = pydantic.Field(default=None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: groundx
3
- Version: 2.0.21
3
+ Version: 2.0.29
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.8,<4.0
@@ -20,18 +20,20 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Classifier: Typing :: Typed
23
+ Requires-Dist: aiohttp (>=3.8.0)
23
24
  Requires-Dist: httpx (>=0.21.2)
24
25
  Requires-Dist: pydantic (>=1.9.2)
25
26
  Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
27
+ Requires-Dist: requests (>=2.4.0)
26
28
  Requires-Dist: typing_extensions (>=4.0.0)
27
29
  Description-Content-Type: text/markdown
28
30
 
29
- # Eyelevel Python Library
31
+ # GroundX Python Library
30
32
 
31
33
  [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Feyelevelai%2Fgroundx-python)
32
34
  [![pypi](https://img.shields.io/pypi/v/groundx)](https://pypi.python.org/pypi/groundx)
33
35
 
34
- The Eyelevel Python library provides convenient access to the Eyelevel API from Python.
36
+ The GroundX Python library provides convenient access to the GroundX API from Python.
35
37
 
36
38
  ## Documentation
37
39
 
@@ -52,14 +54,15 @@ A full reference for this library is available [here](./reference.md).
52
54
  Instantiate and use the client with the following:
53
55
 
54
56
  ```python
55
- from groundx import GroundX, IngestRemoteDocument
57
+ from groundx import Document, GroundX
56
58
 
57
59
  client = GroundX(
58
60
  api_key="YOUR_API_KEY",
59
61
  )
60
- client.documents.ingest_remote(
62
+
63
+ client.ingest(
61
64
  documents=[
62
- IngestRemoteDocument(
65
+ Document(
63
66
  bucket_id=1234,
64
67
  file_name="my_file1.txt",
65
68
  file_type="txt",
@@ -76,17 +79,16 @@ The SDK also exports an `async` client so that you can make non-blocking calls t
76
79
  ```python
77
80
  import asyncio
78
81
 
79
- from groundx import AsyncGroundX, IngestRemoteDocument
82
+ from groundx import AsyncGroundX, Document
80
83
 
81
84
  client = AsyncGroundX(
82
85
  api_key="YOUR_API_KEY",
83
86
  )
84
87
 
85
-
86
88
  async def main() -> None:
87
- await client.documents.ingest_remote(
89
+ await client.ingest(
88
90
  documents=[
89
- IngestRemoteDocument(
91
+ Document(
90
92
  bucket_id=1234,
91
93
  file_name="my_file1.txt",
92
94
  file_type="txt",
@@ -95,7 +97,6 @@ async def main() -> None:
95
97
  ],
96
98
  )
97
99
 
98
-
99
100
  asyncio.run(main())
100
101
  ```
101
102
 
@@ -108,7 +109,7 @@ will be thrown.
108
109
  from groundx.core.api_error import ApiError
109
110
 
110
111
  try:
111
- client.documents.ingest_remote(...)
112
+ client.ingest(...)
112
113
  except ApiError as e:
113
114
  print(e.status_code)
114
115
  print(e.body)
@@ -131,7 +132,7 @@ A request is deemed retriable when any of the following HTTP status codes is ret
131
132
  Use the `max_retries` request option to configure this behavior.
132
133
 
133
134
  ```python
134
- client.documents.ingest_remote(..., request_options={
135
+ client.ingest(..., request_options={
135
136
  "max_retries": 1
136
137
  })
137
138
  ```
@@ -151,7 +152,7 @@ client = GroundX(
151
152
 
152
153
 
153
154
  # Override timeout for a specific method
154
- client.documents.ingest_remote(..., request_options={
155
+ client.ingest(..., request_options={
155
156
  "timeout_in_seconds": 1
156
157
  })
157
158
  ```
@@ -1,10 +1,10 @@
1
- groundx/__init__.py,sha256=_IGBowwyPGd2Yc8c-X8b4FRu5rNA_SoTj4e3bhtB69Y,2975
1
+ groundx/__init__.py,sha256=hl6bFr_FJ0R5Ux_bQErYlWDZQcOF10rkda_r3pah3NQ,3005
2
2
  groundx/buckets/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
3
3
  groundx/buckets/client.py,sha256=TofNrkej1AC_-FU5rf_y8KG8ubFUpHtLa8PQ7rqax6E,26537
4
- groundx/client.py,sha256=Q1Kw0z6K-z-ShhNyuuPe5fYonM9M2I_55-ukUrUWk1U,6507
4
+ groundx/client.py,sha256=dIW9OyrMyfC1N7HSxRrHh0w_8rJ8osNUOPdYD6ueQ6g,6515
5
5
  groundx/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
6
6
  groundx/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
7
- groundx/core/client_wrapper.py,sha256=ZCThAGYPgh2zcfTO99ZP-m7Fdgqktuyv7kfz-Y1Q6FY,1803
7
+ groundx/core/client_wrapper.py,sha256=izkWI7v0-6Cn7v0Nf4TBi2AlORgWXj2AEH_J0jSJkYU,1803
8
8
  groundx/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
9
9
  groundx/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
10
10
  groundx/core/http_client.py,sha256=siUQ6UV0ARZALlxubqWSSAAPC9B4VW8y6MGlHStfaeo,19552
@@ -26,12 +26,13 @@ groundx/groups/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
26
26
  groundx/groups/client.py,sha256=CiCent5Wb8iC2QtR_xI2kNCvMdONuE0-HSfpy3QbL2I,38863
27
27
  groundx/health/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
28
28
  groundx/health/client.py,sha256=fcTa21RWPyBuT77PQ0EncC6rBaW_DrYlRvudy9-0H58,7545
29
+ groundx/ingest.py,sha256=s8FCBUcjARJuvcDZtn0PFzpgzSIplmJwPA0yoRLunQY,11410
29
30
  groundx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
31
  groundx/search/__init__.py,sha256=RagVzjShP33mDg9o4N3kGzV0egL1RYNjCpXPE8VzMYE,145
31
32
  groundx/search/client.py,sha256=10ifg9GyIwIZF13ULfCXF8iFIydq6H6QRDrGPDjpanw,19756
32
33
  groundx/search/types/__init__.py,sha256=fNFXQloPa1PHHO8VZim6KQNMA9N5EZtfSkissdxtY_c,165
33
34
  groundx/search/types/search_content_request_id.py,sha256=us7mYdzR0qPur_wR5I9BhHaLEzC5nLBRna6-xq4M1ec,128
34
- groundx/types/__init__.py,sha256=ViqDRA9l-OWZP4_Zl7nVOvd_EZKpTFFvyYkxdHB9vco,3762
35
+ groundx/types/__init__.py,sha256=GO3it8Adm7ZaxMnc8ZP_9CNZkKpZX7X36hUKi1NgYWA,3809
35
36
  groundx/types/bounding_box_detail.py,sha256=51qcen326NTHY2ZqH1cFXut0_MCmk39EbLoDAwotdq4,1832
36
37
  groundx/types/bucket_detail.py,sha256=bQjCvfyWydjItmzNNTvH-iWxNDOggd7R7X1alFZzlEY,1511
37
38
  groundx/types/bucket_list_response.py,sha256=jC0NBsLCYDSwQrBzuW0g3PWFycjtKl8YRkKhic_-1DA,650
@@ -40,6 +41,7 @@ groundx/types/bucket_update_detail.py,sha256=B4atQMDSXEdx7otcDbvgsrAHtXNz9swMnOs
40
41
  groundx/types/bucket_update_response.py,sha256=h5RJTEpc4WPI_C4sPvsJZo7IxKppnPR-I9VGEQryRlc,633
41
42
  groundx/types/customer_detail.py,sha256=RNm0qXvKx6YvVmkVJZeCNIz7n8_siFMXJ_AGtH3i5Z0,1094
42
43
  groundx/types/customer_response.py,sha256=_RbuanXhCWQkCeQ0dkwPgsjNBoBgNpixiNfRpXcMew8,618
44
+ groundx/types/document.py,sha256=wfhVkqNnYvRmmICXQR-jGp6P1KuJTC7aSq3kE7e9j5s,1691
43
45
  groundx/types/document_detail.py,sha256=i1UfcQAGYo9v1HwrrpzQPw_O0qA7IOXwOUuPV1yU8nI,2323
44
46
  groundx/types/document_list_response.py,sha256=Z0Hm5VBwI0qatbSp6nYHh0RrGwJN3Gqh2D72FfDseZk,839
45
47
  groundx/types/document_local_ingest_request.py,sha256=zqaT_QgYcEc8AfVwZm-O5jLTEiYSsO-i3VVgZ_7xl7w,197
@@ -54,8 +56,8 @@ groundx/types/health_response_health.py,sha256=I0QeEljFp6l5LCJbCTArW031Om84egePg
54
56
  groundx/types/health_service.py,sha256=M1-h1EJSpAXw-j3pY-09_g_WKkO0spdj8e7pgPzSGf0,1083
55
57
  groundx/types/health_service_status.py,sha256=ugKJXlx8QGi83n_J6s1frFrW1hYfOn3Dlb_pPNexwMA,185
56
58
  groundx/types/ingest_local_document.py,sha256=am6TPgHu40S4Lzo9hMkDRauYnc-AWBuYL0Lgk85Fseg,753
57
- groundx/types/ingest_local_document_metadata.py,sha256=I4CSafx8kLSHLbU5_TkU6igy2plevkzUzdsR7vhovHg,1558
58
- groundx/types/ingest_remote_document.py,sha256=xlPA4SYoUgoGXpxZhyORdezxIPGmr4wneav2ZEVmmOY,1683
59
+ groundx/types/ingest_local_document_metadata.py,sha256=TIMHo_4a-sS_ZwveoSmMS3R8SL3k3W7iH49ffcu8W1U,1560
60
+ groundx/types/ingest_remote_document.py,sha256=LpS8R1zWwM07lUaSwrNzTCg9jok8u5tP0EOf2Q9_7eI,1685
59
61
  groundx/types/ingest_response.py,sha256=139rn8wpT44jlUzYXiy0r8XzN2U_OtdLltpSbRU0TyA,633
60
62
  groundx/types/ingest_response_ingest.py,sha256=8FKApYNvS6KFxEKm05pKpKJ0BAagxoE0cWeTt-qjm1g,781
61
63
  groundx/types/message_response.py,sha256=g_FJJyXYg_3fjZQueXkcy11q-qUfZGdVdALddHBieh4,585
@@ -75,9 +77,9 @@ groundx/types/sort.py,sha256=oXap7qO8jI5I2wRhjdEfei4x0sEk2OEId2ll92EFOF8,147
75
77
  groundx/types/sort_order.py,sha256=hfJkStz6zHf3iWQFaVLkNCZPdyj5JS7TsQlN4Ij8Q5A,148
76
78
  groundx/types/subscription_detail.py,sha256=WNfUw2EMVECIvNYcV2s51zZ6T3Utc4zYXw63bPaeM6U,768
77
79
  groundx/types/subscription_detail_meters.py,sha256=lBa8-1QlMVHjr5RLGqhiTKnD1KMM0AAHTWvz9TVtG8w,830
78
- groundx/types/website_source.py,sha256=0TYZqyR16bUO9dfVrNwmph-ICmRzgje02aim1M17x7k,1576
80
+ groundx/types/website_source.py,sha256=3WeRCiilNKKBTfhwgjo3jbcVI3vLTeM-KxI6dVzpg9o,1578
79
81
  groundx/version.py,sha256=1yVogKaq260fQfckM2RYN2144SEw0QROsZW8ICtkG4U,74
80
- groundx-2.0.21.dist-info/LICENSE,sha256=8dMPYAFBTA7O4DUxhrEKEks8CL2waCMYM6dHohW4xrI,1065
81
- groundx-2.0.21.dist-info/METADATA,sha256=4SvJFYtth9J6AYAv5SuzIsB-KGtAaLYVGiqCv_CZD90,5122
82
- groundx-2.0.21.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
83
- groundx-2.0.21.dist-info/RECORD,,
82
+ groundx-2.0.29.dist-info/LICENSE,sha256=8dMPYAFBTA7O4DUxhrEKEks8CL2waCMYM6dHohW4xrI,1065
83
+ groundx-2.0.29.dist-info/METADATA,sha256=mJ8Rov-0ARyaHlYB2ZxhJjh3c81INPhEVP-r6zC1BQ8,5052
84
+ groundx-2.0.29.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
85
+ groundx-2.0.29.dist-info/RECORD,,