exa-py 1.15.1__py3-none-any.whl → 1.15.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of exa-py might be problematic. Click here for more details.

@@ -1,3 +1,3 @@
1
- from .client import ImportsClient
2
-
3
- __all__ = ["ImportsClient"]
1
+ from .client import ImportsClient, AsyncImportsClient
2
+
3
+ __all__ = ["ImportsClient", "AsyncImportsClient"]
@@ -4,7 +4,9 @@ import time
4
4
  import os
5
5
  import csv
6
6
  import io
7
+ import asyncio
7
8
  import requests
9
+ import httpx
8
10
  from typing import Dict, Any, Union, Optional
9
11
  from pathlib import Path
10
12
 
@@ -16,6 +18,7 @@ from ..types import (
16
18
  UpdateImport,
17
19
  )
18
20
  from ..core.base import WebsetsBaseClient
21
+ from ..core.async_base import WebsetsAsyncBaseClient
19
22
 
20
23
  class ImportsClient(WebsetsBaseClient):
21
24
  """Client for managing Imports."""
@@ -176,4 +179,169 @@ class ImportsClient(WebsetsBaseClient):
176
179
  if time.time() - start_time > timeout:
177
180
  raise TimeoutError(f"Import {import_id} did not complete within {timeout} seconds")
178
181
 
179
- time.sleep(poll_interval)
182
+ time.sleep(poll_interval)
183
+
184
+
185
+ class AsyncImportsClient(WebsetsAsyncBaseClient):
186
+ """Async client for managing Imports."""
187
+
188
+ def __init__(self, client):
189
+ super().__init__(client)
190
+
191
+ async def create(
192
+ self,
193
+ params: Union[Dict[str, Any], CreateImportParameters],
194
+ *,
195
+ csv_data: Optional[Union[str, Path]] = None
196
+ ) -> Union[CreateImportResponse, Import]:
197
+ """Create a new import to upload your data into Websets.
198
+
199
+ Imports can be used to:
200
+ - Enrich: Enhance your data with additional information using our AI-powered enrichment engine
201
+ - Search: Query your data using Websets' agentic search with natural language filters
202
+ - Exclude: Prevent duplicate or already known results from appearing in your searches
203
+
204
+ Args:
205
+ params (CreateImportParameters): The parameters for creating an import.
206
+ csv_data (Union[str, Path], optional): CSV data to upload. Can be raw CSV string or file path.
207
+ When provided, size and count will be automatically calculated
208
+ if not specified in params.
209
+
210
+ Returns:
211
+ CreateImportResponse: If csv_data is None (traditional usage with upload URL).
212
+ Import: If csv_data is provided (uploaded and processing).
213
+ """
214
+ if csv_data is not None:
215
+ if isinstance(csv_data, (str, Path)) and os.path.isfile(csv_data):
216
+ # Use synchronous file reading for simplicity (file reading is typically fast)
217
+ with open(csv_data, 'r', encoding='utf-8') as f:
218
+ csv_content = f.read()
219
+ else:
220
+ csv_content = str(csv_data)
221
+
222
+ if isinstance(params, dict):
223
+ current_size = params.get('size')
224
+ current_count = params.get('count')
225
+ else:
226
+ current_size = getattr(params, 'size', None)
227
+ current_count = getattr(params, 'count', None)
228
+
229
+ if current_size is None or current_count is None:
230
+ calculated_size = len(csv_content.encode('utf-8'))
231
+ csv_reader = csv.reader(io.StringIO(csv_content))
232
+ rows = list(csv_reader)
233
+ calculated_count = max(0, len(rows) - 1)
234
+
235
+ if isinstance(params, dict):
236
+ params = params.copy()
237
+ if current_size is None:
238
+ params['size'] = calculated_size
239
+ if current_count is None:
240
+ params['count'] = calculated_count
241
+ else:
242
+ params_dict = params.model_dump()
243
+ if current_size is None:
244
+ params_dict['size'] = calculated_size
245
+ if current_count is None:
246
+ params_dict['count'] = calculated_count
247
+ params = CreateImportParameters.model_validate(params_dict)
248
+
249
+ response = await self.request("/v0/imports", data=params)
250
+ import_response = CreateImportResponse.model_validate(response)
251
+
252
+ if csv_data is None:
253
+ return import_response
254
+
255
+ # Use httpx for async HTTP requests
256
+ async with httpx.AsyncClient() as http_client:
257
+ upload_response = await http_client.put(
258
+ import_response.upload_url,
259
+ data=csv_content,
260
+ headers={'Content-Type': 'text/csv'}
261
+ )
262
+ upload_response.raise_for_status()
263
+
264
+ return await self.get(import_response.id)
265
+
266
+ async def get(self, import_id: str) -> Import:
267
+ """Get a specific import.
268
+
269
+ Args:
270
+ import_id (str): The id of the Import.
271
+
272
+ Returns:
273
+ Import: The retrieved import.
274
+ """
275
+ response = await self.request(f"/v0/imports/{import_id}", method="GET")
276
+ return Import.model_validate(response)
277
+
278
+ async def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None) -> ListImportsResponse:
279
+ """List all imports.
280
+
281
+ Args:
282
+ cursor (str, optional): The cursor to paginate through the results.
283
+ limit (int, optional): The number of results to return (1-200, default 25).
284
+
285
+ Returns:
286
+ ListImportsResponse: List of imports with pagination info.
287
+ """
288
+ params = {
289
+ k: v
290
+ for k, v in {
291
+ "cursor": cursor,
292
+ "limit": limit
293
+ }.items()
294
+ if v is not None
295
+ }
296
+ response = await self.request("/v0/imports", params=params, method="GET")
297
+ return ListImportsResponse.model_validate(response)
298
+
299
+ async def update(self, import_id: str, params: Union[Dict[str, Any], UpdateImport]) -> Import:
300
+ """Update an import configuration.
301
+
302
+ Args:
303
+ import_id (str): The id of the Import.
304
+ params (UpdateImport): The parameters for updating an import.
305
+
306
+ Returns:
307
+ Import: The updated import.
308
+ """
309
+ response = await self.request(f"/v0/imports/{import_id}", data=params, method="PATCH")
310
+ return Import.model_validate(response)
311
+
312
+ async def delete(self, import_id: str) -> Import:
313
+ """Delete an import.
314
+
315
+ Args:
316
+ import_id (str): The id of the Import.
317
+
318
+ Returns:
319
+ Import: The deleted import.
320
+ """
321
+ response = await self.request(f"/v0/imports/{import_id}", method="DELETE")
322
+ return Import.model_validate(response)
323
+
324
+ async def wait_until_completed(self, import_id: str, *, timeout: int = 1800, poll_interval: int = 5) -> Import:
325
+ """Wait until an import is completed or failed.
326
+
327
+ Args:
328
+ import_id (str): The id of the Import.
329
+ timeout (int, optional): Maximum time to wait in seconds. Defaults to 1800 (30 minutes).
330
+ poll_interval (int, optional): Time to wait between polls in seconds. Defaults to 5.
331
+
332
+ Returns:
333
+ Import: The import once it's completed or failed.
334
+
335
+ Raises:
336
+ TimeoutError: If the import does not complete within the timeout period.
337
+ """
338
+ start_time = asyncio.get_event_loop().time()
339
+ while True:
340
+ import_obj = await self.get(import_id)
341
+ if import_obj.status in ['completed', 'failed']:
342
+ return import_obj
343
+
344
+ if asyncio.get_event_loop().time() - start_time > timeout:
345
+ raise TimeoutError(f"Import {import_id} did not complete within {timeout} seconds")
346
+
347
+ await asyncio.sleep(poll_interval)
@@ -1,3 +1,3 @@
1
- from .client import WebsetItemsClient
1
+ from .client import WebsetItemsClient, AsyncWebsetItemsClient
2
2
 
3
- __all__ = ["WebsetItemsClient"]
3
+ __all__ = ["WebsetItemsClient", "AsyncWebsetItemsClient"]
@@ -1,12 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Optional, Iterator
3
+ from typing import Optional, Iterator, AsyncIterator
4
4
 
5
5
  from ..types import (
6
6
  WebsetItem,
7
7
  ListWebsetItemResponse,
8
8
  )
9
9
  from ..core.base import WebsetsBaseClient
10
+ from ..core.async_base import WebsetsAsyncBaseClient
10
11
 
11
12
  class WebsetItemsClient(WebsetsBaseClient):
12
13
  """Client for managing Webset Items."""
@@ -77,4 +78,76 @@ class WebsetItemsClient(WebsetsBaseClient):
77
78
  WebsetItem: The deleted item.
78
79
  """
79
80
  response = self.request(f"/v0/websets/{webset_id}/items/{id}", method="DELETE")
81
+ return WebsetItem.model_validate(response)
82
+
83
+
84
+ class AsyncWebsetItemsClient(WebsetsAsyncBaseClient):
85
+ """Async client for managing Webset Items."""
86
+
87
+ def __init__(self, client):
88
+ super().__init__(client)
89
+
90
+ async def list(self, webset_id: str, *, cursor: Optional[str] = None,
91
+ limit: Optional[int] = None, source_id: Optional[str] = None) -> ListWebsetItemResponse:
92
+ """List all Items for a Webset.
93
+
94
+ Args:
95
+ webset_id (str): The id or externalId of the Webset.
96
+ cursor (str, optional): The cursor to paginate through the results.
97
+ limit (int, optional): The number of results to return (max 200).
98
+ source_id (str, optional): Filter items by source ID.
99
+
100
+ Returns:
101
+ ListWebsetItemResponse: List of webset items.
102
+ """
103
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit, "sourceId": source_id}.items() if v is not None}
104
+ response = await self.request(f"/v0/websets/{webset_id}/items", params=params, method="GET")
105
+ return ListWebsetItemResponse.model_validate(response)
106
+
107
+ async def list_all(self, webset_id: str, *, limit: Optional[int] = None, source_id: Optional[str] = None) -> AsyncIterator[WebsetItem]:
108
+ """Iterate through all Items in a Webset, handling pagination automatically.
109
+
110
+ Args:
111
+ webset_id (str): The id or externalId of the Webset.
112
+ limit (int, optional): The number of results to return per page (max 200).
113
+ source_id (str, optional): Filter items by source ID.
114
+
115
+ Yields:
116
+ WebsetItem: Each item in the webset.
117
+ """
118
+ cursor = None
119
+ while True:
120
+ response = await self.list(webset_id, cursor=cursor, limit=limit, source_id=source_id)
121
+ for item in response.data:
122
+ yield item
123
+
124
+ if not response.has_more or not response.next_cursor:
125
+ break
126
+
127
+ cursor = response.next_cursor
128
+
129
+ async def get(self, webset_id: str, id: str) -> WebsetItem:
130
+ """Get an Item by ID.
131
+
132
+ Args:
133
+ webset_id (str): The id or externalId of the Webset.
134
+ id (str): The id of the Webset item.
135
+
136
+ Returns:
137
+ WebsetItem: The retrieved item.
138
+ """
139
+ response = await self.request(f"/v0/websets/{webset_id}/items/{id}", method="GET")
140
+ return WebsetItem.model_validate(response)
141
+
142
+ async def delete(self, webset_id: str, id: str) -> WebsetItem:
143
+ """Delete an Item.
144
+
145
+ Args:
146
+ webset_id (str): The id or externalId of the Webset.
147
+ id (str): The id of the Webset item.
148
+
149
+ Returns:
150
+ WebsetItem: The deleted item.
151
+ """
152
+ response = await self.request(f"/v0/websets/{webset_id}/items/{id}", method="DELETE")
80
153
  return WebsetItem.model_validate(response)
@@ -1,4 +1,4 @@
1
- from .client import MonitorsClient
2
- from .runs import MonitorRunsClient
1
+ from .client import MonitorsClient, AsyncMonitorsClient
2
+ from .runs import MonitorRunsClient, AsyncMonitorRunsClient
3
3
 
4
- __all__ = ["MonitorsClient", "MonitorRunsClient"]
4
+ __all__ = ["MonitorsClient", "AsyncMonitorsClient", "MonitorRunsClient", "AsyncMonitorRunsClient"]
@@ -9,6 +9,7 @@ from ..types import (
9
9
  ListMonitorsResponse,
10
10
  )
11
11
  from ..core.base import WebsetsBaseClient
12
+ from ..core.async_base import WebsetsAsyncBaseClient
12
13
  from .runs import MonitorRunsClient
13
14
 
14
15
  class MonitorsClient(WebsetsBaseClient):
@@ -93,4 +94,39 @@ class MonitorsClient(WebsetsBaseClient):
93
94
  Monitor: The deleted monitor.
94
95
  """
95
96
  response = self.request(f"/v0/monitors/{monitor_id}", method="DELETE")
97
+ return Monitor.model_validate(response)
98
+
99
+
100
+ class AsyncMonitorsClient(WebsetsAsyncBaseClient):
101
+ """Async client for managing Monitors."""
102
+
103
+ def __init__(self, client):
104
+ super().__init__(client)
105
+ from .runs import AsyncMonitorRunsClient
106
+ self.runs = AsyncMonitorRunsClient(client)
107
+
108
+ async def create(self, params: Union[Dict[str, Any], CreateMonitorParameters]) -> Monitor:
109
+ """Create a new Monitor to continuously keep your Websets updated with fresh data."""
110
+ response = await self.request("/v0/monitors", data=params)
111
+ return Monitor.model_validate(response)
112
+
113
+ async def get(self, monitor_id: str) -> Monitor:
114
+ """Get a specific monitor."""
115
+ response = await self.request(f"/v0/monitors/{monitor_id}", method="GET")
116
+ return Monitor.model_validate(response)
117
+
118
+ async def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None, webset_id: Optional[str] = None) -> ListMonitorsResponse:
119
+ """List all monitors."""
120
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit, "websetId": webset_id}.items() if v is not None}
121
+ response = await self.request("/v0/monitors", params=params, method="GET")
122
+ return ListMonitorsResponse.model_validate(response)
123
+
124
+ async def update(self, monitor_id: str, params: Union[Dict[str, Any], UpdateMonitor]) -> Monitor:
125
+ """Update a monitor configuration."""
126
+ response = await self.request(f"/v0/monitors/{monitor_id}", data=params, method="PATCH")
127
+ return Monitor.model_validate(response)
128
+
129
+ async def delete(self, monitor_id: str) -> Monitor:
130
+ """Delete a monitor."""
131
+ response = await self.request(f"/v0/monitors/{monitor_id}", method="DELETE")
96
132
  return Monitor.model_validate(response)
@@ -1,3 +1,3 @@
1
- from .client import MonitorRunsClient
1
+ from .client import MonitorRunsClient, AsyncMonitorRunsClient
2
2
 
3
- __all__ = ["MonitorRunsClient"]
3
+ __all__ = ["MonitorRunsClient", "AsyncMonitorRunsClient"]
@@ -5,6 +5,7 @@ from ...types import (
5
5
  ListMonitorRunsResponse,
6
6
  )
7
7
  from ...core.base import WebsetsBaseClient
8
+ from ...core.async_base import WebsetsAsyncBaseClient
8
9
 
9
10
  class MonitorRunsClient(WebsetsBaseClient):
10
11
  """Client for managing Monitor Runs."""
@@ -35,4 +36,21 @@ class MonitorRunsClient(WebsetsBaseClient):
35
36
  MonitorRun: The monitor run details.
36
37
  """
37
38
  response = self.request(f"/v0/monitors/{monitor_id}/runs/{run_id}", method="GET")
39
+ return MonitorRun.model_validate(response)
40
+
41
+
42
+ class AsyncMonitorRunsClient(WebsetsAsyncBaseClient):
43
+ """Async client for managing Monitor Runs."""
44
+
45
+ def __init__(self, client):
46
+ super().__init__(client)
47
+
48
+ async def list(self, monitor_id: str) -> ListMonitorRunsResponse:
49
+ """List all runs for the Monitor."""
50
+ response = await self.request(f"/v0/monitors/{monitor_id}/runs", method="GET")
51
+ return ListMonitorRunsResponse.model_validate(response)
52
+
53
+ async def get(self, monitor_id: str, run_id: str) -> MonitorRun:
54
+ """Get a specific monitor run."""
55
+ response = await self.request(f"/v0/monitors/{monitor_id}/runs/{run_id}", method="GET")
38
56
  return MonitorRun.model_validate(response)
@@ -1,3 +1,3 @@
1
- from .client import WebsetSearchesClient
1
+ from .client import WebsetSearchesClient, AsyncWebsetSearchesClient
2
2
 
3
- __all__ = ["WebsetSearchesClient"]
3
+ __all__ = ["WebsetSearchesClient", "AsyncWebsetSearchesClient"]
@@ -7,6 +7,7 @@ from ..types import (
7
7
  WebsetSearch,
8
8
  )
9
9
  from ..core.base import WebsetsBaseClient
10
+ from ..core.async_base import WebsetsAsyncBaseClient
10
11
 
11
12
  class WebsetSearchesClient(WebsetsBaseClient):
12
13
  """Client for managing Webset Searches."""
@@ -51,4 +52,50 @@ class WebsetSearchesClient(WebsetsBaseClient):
51
52
  WebsetSearch: The canceled search.
52
53
  """
53
54
  response = self.request(f"/v0/websets/{webset_id}/searches/{id}/cancel", method="POST")
55
+ return WebsetSearch.model_validate(response)
56
+
57
+
58
+ class AsyncWebsetSearchesClient(WebsetsAsyncBaseClient):
59
+ """Async client for managing Webset Searches."""
60
+
61
+ def __init__(self, client):
62
+ super().__init__(client)
63
+
64
+ async def create(self, webset_id: str, params: Union[Dict[str, Any], CreateWebsetSearchParameters]) -> WebsetSearch:
65
+ """Create a new Search for the Webset.
66
+
67
+ Args:
68
+ webset_id (str): The id of the Webset.
69
+ params (CreateWebsetSearchParameters): The parameters for creating a search.
70
+
71
+ Returns:
72
+ WebsetSearch: The created search.
73
+ """
74
+ response = await self.request(f"/v0/websets/{webset_id}/searches", data=params)
75
+ return WebsetSearch.model_validate(response)
76
+
77
+ async def get(self, webset_id: str, id: str) -> WebsetSearch:
78
+ """Get a Search by ID.
79
+
80
+ Args:
81
+ webset_id (str): The id of the Webset.
82
+ id (str): The id of the Search.
83
+
84
+ Returns:
85
+ WebsetSearch: The retrieved search.
86
+ """
87
+ response = await self.request(f"/v0/websets/{webset_id}/searches/{id}", method="GET")
88
+ return WebsetSearch.model_validate(response)
89
+
90
+ async def cancel(self, webset_id: str, id: str) -> WebsetSearch:
91
+ """Cancel a running Search.
92
+
93
+ Args:
94
+ webset_id (str): The id of the Webset.
95
+ id (str): The id of the Search.
96
+
97
+ Returns:
98
+ WebsetSearch: The canceled search.
99
+ """
100
+ response = await self.request(f"/v0/websets/{webset_id}/searches/{id}/cancel", method="POST")
54
101
  return WebsetSearch.model_validate(response)
exa_py/websets/types.py CHANGED
@@ -24,15 +24,24 @@ class WebsetSearchBehavior(Enum):
24
24
 
25
25
 
26
26
  class MonitorBehaviorSearchConfig(ExaBaseModel):
27
- query: str
28
- criteria: List[SearchCriterion]
29
- entity: Union[
27
+ query: Optional[str] = None
28
+ """
29
+ The query to search for. By default, the query from the last search is used.
30
+ """
31
+ criteria: Optional[List[SearchCriterion]] = None
32
+ """
33
+ The criteria to search for. By default, the criteria from the last search is used.
34
+ """
35
+ entity: Optional[Union[
30
36
  WebsetCompanyEntity,
31
37
  WebsetPersonEntity,
32
38
  WebsetArticleEntity,
33
39
  WebsetResearchPaperEntity,
34
40
  WebsetCustomEntity,
35
- ] = Field(..., title='WebsetEntity')
41
+ ]] = Field(None, title='WebsetEntity')
42
+ """
43
+ The entity to search for. By default, the entity from the last search/import is used.
44
+ """
36
45
  count: int
37
46
  """
38
47
  The maximum number of results to find
@@ -1,3 +1,3 @@
1
- from .client import WebsetWebhooksClient
1
+ from .client import WebsetWebhooksClient, AsyncWebsetWebhooksClient, AsyncWebhookAttemptsClient
2
2
 
3
- __all__ = ["WebsetWebhooksClient"]
3
+ __all__ = ["WebsetWebhooksClient", "AsyncWebsetWebhooksClient", "AsyncWebhookAttemptsClient"]
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Optional, Dict, Any, Union, Literal
3
+ from typing import Optional, Dict, Any, Union
4
4
 
5
5
  from ..types import (
6
6
  CreateWebhookParameters,
@@ -11,6 +11,7 @@ from ..types import (
11
11
  EventType,
12
12
  )
13
13
  from ..core.base import WebsetsBaseClient
14
+ from ..core.async_base import WebsetsAsyncBaseClient
14
15
 
15
16
  class WebhookAttemptsClient(WebsetsBaseClient):
16
17
  """Client for managing Webhook Attempts."""
@@ -118,4 +119,65 @@ class WebsetWebhooksClient(WebsetsBaseClient):
118
119
  Webhook: The deleted webhook.
119
120
  """
120
121
  response = self.request(f"/v0/webhooks/{id}", method="DELETE")
122
+ return Webhook.model_validate(response)
123
+
124
+
125
+ class AsyncWebhookAttemptsClient(WebsetsAsyncBaseClient):
126
+ """Async client for managing Webhook Attempts."""
127
+
128
+ def __init__(self, client):
129
+ super().__init__(client)
130
+
131
+ async def list(self, webhook_id: str, *, cursor: Optional[str] = None,
132
+ limit: Optional[int] = None, event_type: Optional[Union[EventType, str]] = None,
133
+ successful: Optional[bool] = None) -> ListWebhookAttemptsResponse:
134
+ """List all attempts made by a Webhook ordered in descending order."""
135
+ event_type_value = None
136
+ if event_type is not None:
137
+ if isinstance(event_type, EventType):
138
+ event_type_value = event_type.value
139
+ else:
140
+ event_type_value = event_type
141
+
142
+ params = {k: v for k, v in {
143
+ "cursor": cursor,
144
+ "limit": limit,
145
+ "eventType": event_type_value,
146
+ "successful": successful
147
+ }.items() if v is not None}
148
+
149
+ response = await self.request(f"/v0/webhooks/{webhook_id}/attempts", params=params, method="GET")
150
+ return ListWebhookAttemptsResponse.model_validate(response)
151
+
152
+ class AsyncWebsetWebhooksClient(WebsetsAsyncBaseClient):
153
+ """Async client for managing Webset Webhooks."""
154
+
155
+ def __init__(self, client):
156
+ super().__init__(client)
157
+ self.attempts = AsyncWebhookAttemptsClient(client)
158
+
159
+ async def create(self, params: Union[Dict[str, Any], CreateWebhookParameters]) -> Webhook:
160
+ """Create a Webhook."""
161
+ response = await self.request("/v0/webhooks", data=params)
162
+ return Webhook.model_validate(response)
163
+
164
+ async def get(self, id: str) -> Webhook:
165
+ """Get a Webhook by ID."""
166
+ response = await self.request(f"/v0/webhooks/{id}", method="GET")
167
+ return Webhook.model_validate(response)
168
+
169
+ async def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None) -> ListWebhooksResponse:
170
+ """List all Webhooks."""
171
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit}.items() if v is not None}
172
+ response = await self.request("/v0/webhooks", params=params, method="GET")
173
+ return ListWebhooksResponse.model_validate(response)
174
+
175
+ async def update(self, id: str, params: Union[Dict[str, Any], UpdateWebhookParameters]) -> Webhook:
176
+ """Update a Webhook."""
177
+ response = await self.request(f"/v0/webhooks/{id}", data=params, method="PATCH")
178
+ return Webhook.model_validate(response)
179
+
180
+ async def delete(self, id: str) -> Webhook:
181
+ """Delete a Webhook."""
182
+ response = await self.request(f"/v0/webhooks/{id}", method="DELETE")
121
183
  return Webhook.model_validate(response)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exa-py
3
- Version: 1.15.1
3
+ Version: 1.15.3
4
4
  Summary: Python SDK for Exa API.
5
5
  License: MIT
6
6
  Author: Exa AI
@@ -0,0 +1,37 @@
1
+ exa_py/__init__.py,sha256=M2GC9oSdoV6m2msboW0vMWWl8wrth4o6gmEV4MYLGG8,66
2
+ exa_py/api.py,sha256=ftJRM7qnF-Ki4agnG4PLtCn7YcrBV1JlC_TmhH5bbG4,109112
3
+ exa_py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ exa_py/research/__init__.py,sha256=qbWY5c3LYBM7L4yGVtiMs9nUg_kMcAVhMhT0DvN6EI4,1014
5
+ exa_py/research/async_client.py,sha256=zNPVLyI_8pPnUypyVAWOBTMpwgCuvFGY2GH5WHeQJMI,9488
6
+ exa_py/research/base.py,sha256=0C52XGUMRwRox1JSVBrbiHZxqPI6Cgif7EFNqYxpc40,5451
7
+ exa_py/research/models.py,sha256=P2vNjdUUebi6OJSFB5jvE9Qd47MKw05Miib9aS1kiTk,10286
8
+ exa_py/research/sync_client.py,sha256=LHMkgqUZgKCQWgLP41Fj6EWLbt_YfX4aAgvWGjNgbXM,9155
9
+ exa_py/research/utils.py,sha256=YR61UkReyK-LrvOTaX_aG_neS1DsmCkv7B6YODpwHvU,5965
10
+ exa_py/utils.py,sha256=1jwKwcJwHSbrzwgMkprXSEZ-xssCtXxwf-GTRgaFmz8,6395
11
+ exa_py/websets/__init__.py,sha256=8ZWndRgeTKceZ3Wcm5xCh_dykrKkoCYdZdKcK7C3aSw,226
12
+ exa_py/websets/_generator/pydantic/BaseModel.jinja2,sha256=RUDCmPZVamoVx1WudylscYFfDhGoNNtRYlpTvKjAiuA,1276
13
+ exa_py/websets/async_client.py,sha256=fewb7T64Ip5R67sZ2fceHv-Lv0gJPqQrsXq-v6ZuZPY,5823
14
+ exa_py/websets/client.py,sha256=mdzZSfzgajfPQKWmjvwhUqjJSrtm3aErKcv4zcp7tWI,11137
15
+ exa_py/websets/core/__init__.py,sha256=L8dLhlle-Y7yoo0p0s60S07UyknyrcEn64W9JxkvCjM,458
16
+ exa_py/websets/core/async_base.py,sha256=RlJEaNR7OfZFzSy4sCk5aiPNT3cztuFZIyfP5vXMGtI,3121
17
+ exa_py/websets/core/base.py,sha256=RldWYwBg2iVfkWmdPke7xjXdwb4JKeABIOgiZtqvz-4,4125
18
+ exa_py/websets/enrichments/__init__.py,sha256=DA57V8s3169lfMnnLcFIOMQxhFIZ9I0uwXPYZMJzs9A,145
19
+ exa_py/websets/enrichments/client.py,sha256=EStsgPgAggEa0FiYrIG9HNZ30akuUrXtKY27f-Fa3sI,5903
20
+ exa_py/websets/events/__init__.py,sha256=VfJzObC3rSstdqz6q2ePnOIRW50GKJoSSH3-mpmDG0w,100
21
+ exa_py/websets/events/client.py,sha256=_jLGUlf27W5XYa7AeUVVvJ9hffwbPZ7981Qz-Fi6U1c,7691
22
+ exa_py/websets/imports/__init__.py,sha256=5fxYvRQdJQsVngvuq278Yw5W0Ckw17I_aPRrrtPcJ1w,105
23
+ exa_py/websets/imports/client.py,sha256=Zr_qWO1rhYTXm62Jz5bR7orfvzDhcb7pHVfeO8uvVmQ,13700
24
+ exa_py/websets/items/__init__.py,sha256=aJZto81Zp9eK1Dou2cFrRXgv3ZBuEvCHqb2G4KuKoao,121
25
+ exa_py/websets/items/client.py,sha256=74vRjMrEoy6cVA8679dFtD43IU2jKDH8Zlw4hLIRs8I,6027
26
+ exa_py/websets/monitors/__init__.py,sha256=cTRxTrsUuQmmmVEN3ewKsOq26xxiBJKTy7v0UjdOooc,216
27
+ exa_py/websets/monitors/client.py,sha256=PmIkizecQSLnicKpIPEBJafId9rx_iJlP-LD_ApuAik,5333
28
+ exa_py/websets/monitors/runs/__init__.py,sha256=rfE6PmQds4uPAd0fN3u992pG7INwbx1QvdyH8M-t8rs,121
29
+ exa_py/websets/monitors/runs/client.py,sha256=_fMPqxzF0gy5g76wU6N8i7XrKTtq5vaOrrIzXkM1ZcA,1985
30
+ exa_py/websets/searches/__init__.py,sha256=w6fJnCTKwl07GWgRVKQbYkPcoAct975YyOZog37C2q8,133
31
+ exa_py/websets/searches/client.py,sha256=_mCuQtdLvKus5ofgs2a9MtY56Zg07JBJzqIg6YWre2A,3495
32
+ exa_py/websets/types.py,sha256=naBzmlJ-nZK3ynDGBE15lmItD5p8-x_OfsWGFpKZRDs,50874
33
+ exa_py/websets/webhooks/__init__.py,sha256=DMl6RFkS0c79AWzkuHOXnaU5QKHmkIHYW2PhZWUFIGc,191
34
+ exa_py/websets/webhooks/client.py,sha256=rdYU0DZKAslw5LwGKB567j3T8L34ZF9tSnlN9jLi23A,7143
35
+ exa_py-1.15.3.dist-info/METADATA,sha256=O64a58jO-ZeKkgwuvYY-JL5szCfqftlRkHA9MyfZ54E,3826
36
+ exa_py-1.15.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
37
+ exa_py-1.15.3.dist-info/RECORD,,
@@ -1,35 +0,0 @@
1
- exa_py/__init__.py,sha256=M2GC9oSdoV6m2msboW0vMWWl8wrth4o6gmEV4MYLGG8,66
2
- exa_py/api.py,sha256=gUvQ2NXtUgBlrFrWrCIUwiq-z2lAlo_gWVFncN68Vhw,108947
3
- exa_py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- exa_py/research/__init__.py,sha256=qbWY5c3LYBM7L4yGVtiMs9nUg_kMcAVhMhT0DvN6EI4,1014
5
- exa_py/research/async_client.py,sha256=jP6BF8nc29Mt4iU2ZEQGAC5dGM-Z9I4k3pzpPcCKJIs,9436
6
- exa_py/research/base.py,sha256=0C52XGUMRwRox1JSVBrbiHZxqPI6Cgif7EFNqYxpc40,5451
7
- exa_py/research/models.py,sha256=2gu4jckbLYHlTmln8BhDzovuqg1fejTCncqi4r0oDow,9822
8
- exa_py/research/sync_client.py,sha256=LHMkgqUZgKCQWgLP41Fj6EWLbt_YfX4aAgvWGjNgbXM,9155
9
- exa_py/research/utils.py,sha256=YR61UkReyK-LrvOTaX_aG_neS1DsmCkv7B6YODpwHvU,5965
10
- exa_py/utils.py,sha256=1jwKwcJwHSbrzwgMkprXSEZ-xssCtXxwf-GTRgaFmz8,6395
11
- exa_py/websets/__init__.py,sha256=x7Dc0MS8raRXA7Ud6alKgnsUmLi6X9GTqfB8kOwC9iQ,179
12
- exa_py/websets/_generator/pydantic/BaseModel.jinja2,sha256=RUDCmPZVamoVx1WudylscYFfDhGoNNtRYlpTvKjAiuA,1276
13
- exa_py/websets/client.py,sha256=sKkji8QaPFnGM1-J5TB6yKJcGAEd6gk7lsnIebzXNQ8,5856
14
- exa_py/websets/core/__init__.py,sha256=xOyrFaqtBocMUu321Jpbk7IzIQRNZufSIGJXrKoG-Bg,323
15
- exa_py/websets/core/base.py,sha256=RldWYwBg2iVfkWmdPke7xjXdwb4JKeABIOgiZtqvz-4,4125
16
- exa_py/websets/enrichments/__init__.py,sha256=5dJIEKKceUost3RnI6PpCSB3VjUCBzxseEsIXu-ZY-Y,83
17
- exa_py/websets/enrichments/client.py,sha256=Qn6B19Gf1z4pQ5CCeXMFeTJnVi2OiVx9Ck5XlcQBZVI,2999
18
- exa_py/websets/events/__init__.py,sha256=aFJ9O5UudtQQzndVmdB96IaM2l07qyM1B_8xKY7rp58,60
19
- exa_py/websets/events/client.py,sha256=-7sQ61P0SdHj-LuYq6G0u9a_IrtmcCljyDCzZPf330U,4370
20
- exa_py/websets/imports/__init__.py,sha256=iEl-fZZSdcvKaqLgjMES_0RwYn7hZDCMf6BZriCrjgw,64
21
- exa_py/websets/imports/client.py,sha256=nJs46hxlSkZm7qjboYHNBuJ62gLmA_Yzr9fc-NDky0Y,6795
22
- exa_py/websets/items/__init__.py,sha256=DCWZJVtRmUjnMEkKdb5gW1LT9cHcb-J8lENMnyyBeKU,71
23
- exa_py/websets/items/client.py,sha256=stAQ47AgkJdEsNb1E_YAXLe96VrtglOZsG79KVcy--M,3038
24
- exa_py/websets/monitors/__init__.py,sha256=jfr-gq8eKVa_gNe_DEqX9XCZPbJjpOe7QpH_D4RCFJQ,122
25
- exa_py/websets/monitors/client.py,sha256=fFxCSngkUPXqf9ilUMl8DaO2ihYveD-WfSoqARwf1eQ,3526
26
- exa_py/websets/monitors/runs/__init__.py,sha256=TmcETf3zdQouA_vAeLiosCNL1MYJnZ0yW2sbOAjTmm8,71
27
- exa_py/websets/monitors/runs/client.py,sha256=WnwcWCf7UKk68VCNUp8mRXBtlU8vglTSX-eoWVXzKIw,1229
28
- exa_py/websets/searches/__init__.py,sha256=_0Zx8ES5fFTEL3T8mhLxq_xK2t0JONx6ad6AtbvClsE,77
29
- exa_py/websets/searches/client.py,sha256=X3f7axWGfecmxf-2tBTX0Yf_--xToz1X8ZHbbudEzy0,1790
30
- exa_py/websets/types.py,sha256=iDZqvt22hjhkU8_AIczQ9iHexUw9C4PHh7C66ujfhk4,50523
31
- exa_py/websets/webhooks/__init__.py,sha256=iTPBCxFd73z4RifLQMX6iRECx_6pwlI5qscLNjMOUHE,77
32
- exa_py/websets/webhooks/client.py,sha256=zS1eoWKliuiY4AIeFJdpAlPZeOINyphn7KEWANF-zaE,4384
33
- exa_py-1.15.1.dist-info/METADATA,sha256=6MtMgPdsfzWgOKeQtywu4aZASbZjYpetbiirn17CzjE,3826
34
- exa_py-1.15.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
35
- exa_py-1.15.1.dist-info/RECORD,,