exa-py 1.10.0__py3-none-any.whl → 1.11.0__py3-none-any.whl

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

Potentially problematic release.


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

exa_py/api.py CHANGED
@@ -840,7 +840,7 @@ class Exa:
840
840
  self,
841
841
  api_key: Optional[str],
842
842
  base_url: str = "https://api.exa.ai",
843
- user_agent: str = "exa-py 1.10.0",
843
+ user_agent: str = "exa-py 1.11.0",
844
844
  ):
845
845
  """Initialize the Exa client with the provided API key and optional base URL and user agent.
846
846
 
@@ -1826,6 +1826,7 @@ class Exa:
1826
1826
  *,
1827
1827
  stream: Optional[bool] = False,
1828
1828
  text: Optional[bool] = False,
1829
+ system_prompt: Optional[str] = None,
1829
1830
  model: Optional[Literal["exa", "exa-pro"]] = None,
1830
1831
  ) -> Union[AnswerResponse, StreamAnswerResponse]: ...
1831
1832
 
@@ -1835,6 +1836,7 @@ class Exa:
1835
1836
  *,
1836
1837
  stream: Optional[bool] = False,
1837
1838
  text: Optional[bool] = False,
1839
+ system_prompt: Optional[str] = None,
1838
1840
  model: Optional[Literal["exa", "exa-pro"]] = None,
1839
1841
  ) -> Union[AnswerResponse, StreamAnswerResponse]:
1840
1842
  """Generate an answer to a query using Exa's search and LLM capabilities.
@@ -1842,6 +1844,7 @@ class Exa:
1842
1844
  Args:
1843
1845
  query (str): The query to answer.
1844
1846
  text (bool, optional): Whether to include full text in the results. Defaults to False.
1847
+ system_prompt (str, optional): A system prompt to guide the LLM's behavior when generating the answer.
1845
1848
  model (str, optional): The model to use for answering. Either "exa" or "exa-pro". Defaults to None.
1846
1849
 
1847
1850
  Returns:
@@ -1870,6 +1873,7 @@ class Exa:
1870
1873
  query: str,
1871
1874
  *,
1872
1875
  text: bool = False,
1876
+ system_prompt: Optional[str] = None,
1873
1877
  model: Optional[Literal["exa", "exa-pro"]] = None,
1874
1878
  ) -> StreamAnswerResponse:
1875
1879
  """Generate a streaming answer response.
@@ -1877,6 +1881,7 @@ class Exa:
1877
1881
  Args:
1878
1882
  query (str): The query to answer.
1879
1883
  text (bool): Whether to include full text in the results. Defaults to False.
1884
+ system_prompt (str, optional): A system prompt to guide the LLM's behavior when generating the answer.
1880
1885
  model (str, optional): The model to use for answering. Either "exa" or "exa-pro". Defaults to None.
1881
1886
 
1882
1887
  Returns:
@@ -2165,6 +2170,7 @@ class AsyncExa(Exa):
2165
2170
  *,
2166
2171
  stream: Optional[bool] = False,
2167
2172
  text: Optional[bool] = False,
2173
+ system_prompt: Optional[str] = None,
2168
2174
  model: Optional[Literal["exa", "exa-pro"]] = None,
2169
2175
  ) -> Union[AnswerResponse, StreamAnswerResponse]:
2170
2176
  """Generate an answer to a query using Exa's search and LLM capabilities.
@@ -2172,6 +2178,7 @@ class AsyncExa(Exa):
2172
2178
  Args:
2173
2179
  query (str): The query to answer.
2174
2180
  text (bool, optional): Whether to include full text in the results. Defaults to False.
2181
+ system_prompt (str, optional): A system prompt to guide the LLM's behavior when generating the answer.
2175
2182
  model (str, optional): The model to use for answering. Either "exa" or "exa-pro". Defaults to None.
2176
2183
 
2177
2184
  Returns:
@@ -2200,6 +2207,7 @@ class AsyncExa(Exa):
2200
2207
  query: str,
2201
2208
  *,
2202
2209
  text: bool = False,
2210
+ system_prompt: Optional[str] = None,
2203
2211
  model: Optional[Literal["exa", "exa-pro"]] = None,
2204
2212
  ) -> AsyncStreamAnswerResponse:
2205
2213
  """Generate a streaming answer response.
@@ -2207,6 +2215,7 @@ class AsyncExa(Exa):
2207
2215
  Args:
2208
2216
  query (str): The query to answer.
2209
2217
  text (bool): Whether to include full text in the results. Defaults to False.
2218
+ system_prompt (str, optional): A system prompt to guide the LLM's behavior when generating the answer.
2210
2219
  model (str, optional): The model to use for answering. Either "exa" or "exa-pro". Defaults to None.
2211
2220
 
2212
2221
  Returns:
@@ -0,0 +1,958 @@
1
+ ################################
2
+ # Websets Client Code (client.py)
3
+ ################################
4
+
5
+ from __future__ import annotations
6
+
7
+ import time
8
+ from datetime import datetime
9
+ from typing import List, Optional, Literal
10
+
11
+ from .types import (
12
+ Webset,
13
+ ListWebsetsResponse,
14
+ GetWebsetResponse,
15
+ UpdateWebsetRequest,
16
+ WebsetStatus,
17
+ CreateWebsetParameters,
18
+ )
19
+ from .core.base import WebsetsBaseClient
20
+ from .items import WebsetItemsClient
21
+ from .searches import WebsetSearchesClient
22
+ from .enrichments import WebsetEnrichmentsClient
23
+ from .webhooks import WebsetWebhooksClient
24
+
25
+ class WebsetsClient(WebsetsBaseClient):
26
+ """Client for managing Websets."""
27
+
28
+ def __init__(self, client):
29
+ super().__init__(client)
30
+ self.items = WebsetItemsClient(client)
31
+ self.searches = WebsetSearchesClient(client)
32
+ self.enrichments = WebsetEnrichmentsClient(client)
33
+ self.webhooks = WebsetWebhooksClient(client)
34
+
35
+ def create(self, params: CreateWebsetParameters) -> Webset:
36
+ """Create a new Webset."""
37
+ response = self.request("/v0/websets", data=params.model_dump(by_alias=True, exclude_none=True))
38
+ return Webset.model_validate(response)
39
+
40
+ def get(self, id: str, *, expand: Optional[List[Literal["items"]]] = None) -> GetWebsetResponse:
41
+ """Get a Webset by ID."""
42
+ params = {"expand": expand} if expand else {}
43
+ response = self.request(f"/v0/websets/{id}", params=params, method="GET")
44
+ return GetWebsetResponse.model_validate(response)
45
+
46
+ def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None) -> ListWebsetsResponse:
47
+ """List all Websets."""
48
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit}.items() if v is not None}
49
+ response = self.request("/v0/websets", params=params, method="GET")
50
+ return ListWebsetsResponse.model_validate(response)
51
+
52
+ def update(self, id: str, params: UpdateWebsetRequest) -> Webset:
53
+ """Update a Webset."""
54
+ response = self.request(f"/v0/websets/{id}", data=params.model_dump(by_alias=True, exclude_none=True), method="POST")
55
+ return Webset.model_validate(response)
56
+
57
+ def delete(self, id: str) -> Webset:
58
+ """Delete a Webset."""
59
+ response = self.request(f"/v0/websets/{id}", method="DELETE")
60
+ return Webset.model_validate(response)
61
+
62
+ def cancel(self, id: str) -> Webset:
63
+ """Cancel a running Webset."""
64
+ response = self.request(f"/v0/websets/{id}/cancel", method="POST")
65
+ return Webset.model_validate(response)
66
+
67
+ def wait_until_idle(self, id: str, *, timeout: Optional[int] = None) -> Webset:
68
+ """Wait until a Webset is idle."""
69
+ start_time = time.time()
70
+ while True:
71
+ webset = self.get(id)
72
+ if webset.status == WebsetStatus.idle:
73
+ break
74
+ time.sleep(1)
75
+ if timeout and time.time() - start_time > timeout:
76
+ raise Exception("Webset timed out")
77
+ return webset
78
+
79
+ ################################
80
+ # Core Base (core/base.py)
81
+ ################################
82
+
83
+ from __future__ import annotations
84
+
85
+ from pydantic import ConfigDict
86
+ from typing import Any, Dict, Optional
87
+ from pydantic import BaseModel
88
+
89
+ class ExaBaseModel(BaseModel):
90
+ """Base model for all Exa models with common configuration."""
91
+ model_config = ConfigDict(populate_by_name=True)
92
+
93
+ class WebsetsBaseClient:
94
+ base_url: str
95
+
96
+ """Base client for Exa API resources."""
97
+
98
+ def __init__(self, client):
99
+ """Initialize the client."""
100
+ self._client = client
101
+
102
+ def request(self, endpoint: str, data: Optional[Dict[str, Any]] = None,
103
+ method: str = "POST", params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
104
+ """Make a request to the Exa API."""
105
+ return self._client.request("/websets/" + endpoint, data=data, method=method, params=params)
106
+
107
+ ################################
108
+ # Types (types.py)
109
+ ################################
110
+
111
+ from __future__ import annotations
112
+
113
+ from datetime import datetime
114
+ from enum import Enum
115
+ from typing import Any, Dict, List, Literal, Optional, Union
116
+
117
+ from pydantic import AnyUrl, Field, confloat, constr
118
+ from .core.base import ExaBaseModel
119
+
120
+
121
+ class CanceledReason(Enum):
122
+ """The reason the search was canceled"""
123
+ webset_deleted = 'webset_deleted'
124
+ webset_canceled = 'webset_canceled'
125
+
126
+
127
+ class CreateCriterionParameters(ExaBaseModel):
128
+ description: constr(min_length=1, max_length=300)
129
+ """The description of the criterion"""
130
+
131
+
132
+ class CreateEnrichmentParameters(ExaBaseModel):
133
+ description: constr(min_length=1, max_length=5000)
134
+ """Provide a description of the enrichment task you want to perform to each Webset Item."""
135
+ format: Optional[str] = None
136
+ """Format of the enrichment response."""
137
+ options: Optional[List[Option]] = Field(None, max_items=20, min_items=1)
138
+ """When the format is options, the different options for the enrichment agent to choose from."""
139
+ metadata: Optional[Dict[str, Any]] = None
140
+ """Set of key-value pairs you want to associate with this object."""
141
+
142
+
143
+ class CreateWebhookParameters(ExaBaseModel):
144
+ events: List[Event] = Field(..., max_items=12, min_items=1)
145
+ """The events to trigger the webhook"""
146
+ url: AnyUrl
147
+ """The URL to send the webhook to"""
148
+ metadata: Optional[Dict[str, Any]] = None
149
+ """Set of key-value pairs you want to associate with this object."""
150
+
151
+
152
+ class CreateWebsetParameters(ExaBaseModel):
153
+ search: Search
154
+ """Create initial search for the Webset."""
155
+ enrichments: Optional[List[CreateEnrichmentParameters]] = Field(None, max_items=10)
156
+ """Add Enrichments for the Webset."""
157
+ external_id: Optional[str] = Field(None, alias='externalId')
158
+ """The external identifier for the webset."""
159
+ metadata: Optional[Dict[str, Any]] = None
160
+ """Set of key-value pairs you want to associate with this object."""
161
+
162
+
163
+ class CreateWebsetSearchParameters(ExaBaseModel):
164
+ count: confloat(ge=1.0)
165
+ """Number of Items the Search will attempt to find."""
166
+ query: constr(min_length=1, max_length=5000) = Field(
167
+ ...,
168
+ examples=[
169
+ 'Marketing agencies based in the US, that focus on consumer products. Get brands worked with and city'
170
+ ],
171
+ )
172
+ """Query describing what you are looking for."""
173
+ entity: Optional[
174
+ Union[
175
+ WebsetCompanyEntity,
176
+ WebsetPersonEntity,
177
+ WebsetArticleEntity,
178
+ WebsetResearchPaperEntity,
179
+ WebsetCustomEntity,
180
+ ]
181
+ ] = None
182
+ """Entity the Webset will return results for."""
183
+ criteria: Optional[List[CreateCriterionParameters]] = Field(
184
+ None, max_items=5, min_items=1
185
+ )
186
+ """Criteria every item is evaluated against."""
187
+ behaviour: Optional[WebsetSearchBehaviour] = Field(
188
+ 'override', title='WebsetSearchBehaviour'
189
+ )
190
+ """The behaviour of the Search when it is added to a Webset."""
191
+ metadata: Optional[Dict[str, Any]] = None
192
+ """Set of key-value pairs you want to associate with this object."""
193
+
194
+
195
+ class Criterion(ExaBaseModel):
196
+ description: constr(min_length=1, max_length=300)
197
+ """The description of the criterion"""
198
+ success_rate: confloat(ge=0.0, le=100.0) = Field(..., alias='successRate')
199
+ """Value between 0 and 100 representing the percentage of results that meet the criterion."""
200
+
201
+
202
+ class EnrichmentResult(ExaBaseModel):
203
+ object: Literal['enrichment_result']
204
+ format: WebsetEnrichmentFormat
205
+ result: List[str]
206
+ """The result of the enrichment."""
207
+ reasoning: Optional[str] = None
208
+ """The reasoning for the result when an Agent is used."""
209
+ references: List[Reference]
210
+ """The references used to generate the result."""
211
+ enrichment_id: str = Field(..., alias='enrichmentId')
212
+ """The id of the Enrichment that generated the result"""
213
+
214
+
215
+ class Event(Enum):
216
+ webset_created = 'webset.created'
217
+ webset_deleted = 'webset.deleted'
218
+ webset_paused = 'webset.paused'
219
+ webset_idle = 'webset.idle'
220
+ webset_search_created = 'webset.search.created'
221
+ webset_search_canceled = 'webset.search.canceled'
222
+ webset_search_completed = 'webset.search.completed'
223
+ webset_search_updated = 'webset.search.updated'
224
+ webset_export_created = 'webset.export.created'
225
+ webset_export_completed = 'webset.export.completed'
226
+ webset_item_created = 'webset.item.created'
227
+ webset_item_enriched = 'webset.item.enriched'
228
+
229
+
230
+ class Format(Enum):
231
+ """Format of the enrichment response."""
232
+ text = 'text'
233
+ date = 'date'
234
+ number = 'number'
235
+ options = 'options'
236
+ email = 'email'
237
+ phone = 'phone'
238
+
239
+
240
+ class ListEventsResponse(ExaBaseModel):
241
+ data: List[
242
+ Union[
243
+ WebsetCreatedEvent,
244
+ WebsetDeletedEvent,
245
+ WebsetIdleEvent,
246
+ WebsetPausedEvent,
247
+ WebsetItemCreatedEvent,
248
+ WebsetItemEnrichedEvent,
249
+ WebsetSearchCreatedEvent,
250
+ WebsetSearchUpdatedEvent,
251
+ WebsetSearchCanceledEvent,
252
+ WebsetSearchCompletedEvent,
253
+ ]
254
+ ] = Field(..., discriminator='type')
255
+ """The list of events"""
256
+ has_more: bool = Field(..., alias='hasMore')
257
+ """Whether there are more results to paginate through"""
258
+ next_cursor: Optional[str] = Field(..., alias='nextCursor')
259
+ """The cursor to paginate through the next set of results"""
260
+
261
+
262
+ class ListWebhooksResponse(ExaBaseModel):
263
+ data: List[Webhook]
264
+ """The list of webhooks"""
265
+ has_more: bool = Field(..., alias='hasMore')
266
+ """Whether there are more results to paginate through"""
267
+ next_cursor: Optional[str] = Field(..., alias='nextCursor')
268
+ """The cursor to paginate through the next set of results"""
269
+
270
+
271
+ class ListWebsetItemResponse(ExaBaseModel):
272
+ data: List[WebsetItem]
273
+ """The list of webset items"""
274
+ has_more: bool = Field(..., alias='hasMore')
275
+ """Whether there are more Items to paginate through"""
276
+ next_cursor: Optional[str] = Field(..., alias='nextCursor')
277
+ """The cursor to paginate through the next set of Items"""
278
+
279
+
280
+ class ListWebsetsResponse(ExaBaseModel):
281
+ data: List[Webset]
282
+ """The list of websets"""
283
+ has_more: bool = Field(..., alias='hasMore')
284
+ """Whether there are more results to paginate through"""
285
+ next_cursor: Optional[str] = Field(..., alias='nextCursor')
286
+ """The cursor to paginate through the next set of results"""
287
+
288
+
289
+ class Option(ExaBaseModel):
290
+ label: str
291
+ """The label of the option"""
292
+
293
+
294
+ class Progress(ExaBaseModel):
295
+ """The progress of the search"""
296
+ found: float
297
+ """The number of results found so far"""
298
+ completion: confloat(ge=0.0, le=100.0)
299
+ """The completion percentage of the search"""
300
+
301
+
302
+ class Reference(ExaBaseModel):
303
+ title: Optional[str] = None
304
+ """The title of the reference"""
305
+ snippet: Optional[str] = None
306
+ """The relevant snippet of the reference content"""
307
+ url: AnyUrl
308
+ """The URL of the reference"""
309
+
310
+
311
+ class Satisfied(Enum):
312
+ """The satisfaction of the criterion"""
313
+ yes = 'yes'
314
+ no = 'no'
315
+ unclear = 'unclear'
316
+
317
+
318
+ class Search(ExaBaseModel):
319
+ """Create initial search for the Webset."""
320
+ query: constr(min_length=1, max_length=5000) = Field(
321
+ ...,
322
+ examples=[
323
+ 'Marketing agencies based in the US, that focus on consumer products.'
324
+ ],
325
+ )
326
+ """Your search query."""
327
+ count: confloat(ge=1.0)
328
+ """Number of Items the Webset will attempt to find."""
329
+ entity: Optional[
330
+ Union[
331
+ WebsetCompanyEntity,
332
+ WebsetPersonEntity,
333
+ WebsetArticleEntity,
334
+ WebsetResearchPaperEntity,
335
+ WebsetCustomEntity,
336
+ ]
337
+ ] = Field(None, discriminator='type')
338
+ """Entity the Webset will return results for."""
339
+ criteria: Optional[List[CreateCriterionParameters]] = Field(
340
+ None, max_items=5, min_items=1
341
+ )
342
+ """Criteria every item is evaluated against."""
343
+
344
+
345
+ class Source(Enum):
346
+ """The source of the Item"""
347
+ search = 'search'
348
+
349
+
350
+ class UpdateWebhookParameters(ExaBaseModel):
351
+ events: Optional[List[Event]] = Field(None, max_items=12, min_items=1)
352
+ """The events to trigger the webhook"""
353
+ url: Optional[AnyUrl] = None
354
+ """The URL to send the webhook to"""
355
+ metadata: Optional[Dict[str, Any]] = None
356
+ """Set of key-value pairs you want to associate with this object."""
357
+
358
+
359
+ class UpdateWebsetRequest(ExaBaseModel):
360
+ metadata: Optional[Dict[str, Any]] = None
361
+ """Set of key-value pairs you want to associate with this object."""
362
+
363
+
364
+ class Webhook(ExaBaseModel):
365
+ id: str
366
+ """The unique identifier for the webhook"""
367
+ object: Literal['webhook']
368
+ status: WebhookStatus = Field(..., title='WebhookStatus')
369
+ """The status of the webhook"""
370
+ events: List[Event] = Field(..., min_items=1)
371
+ """The events to trigger the webhook"""
372
+ url: AnyUrl
373
+ """The URL to send the webhook to"""
374
+ metadata: Optional[Dict[str, Any]] = None
375
+ """The metadata of the webhook"""
376
+ created_at: datetime = Field(..., alias='createdAt')
377
+ """The date and time the webhook was created"""
378
+ updated_at: datetime = Field(..., alias='updatedAt')
379
+ """The date and time the webhook was last updated"""
380
+
381
+
382
+ class WebhookStatus(Enum):
383
+ """The status of the webhook"""
384
+ active = 'active'
385
+ inactive = 'inactive'
386
+
387
+
388
+ class Webset(ExaBaseModel):
389
+ id: str
390
+ """The unique identifier for the webset"""
391
+ object: Literal['webset']
392
+ status: WebsetStatus = Field(..., title='WebsetStatus')
393
+ """The status of the webset"""
394
+ external_id: Optional[str] = Field(..., alias='externalId')
395
+ """The external identifier for the webset"""
396
+ searches: List[WebsetSearch]
397
+ """The searches that have been performed on the webset."""
398
+ enrichments: List[WebsetEnrichment]
399
+ """The Enrichments to apply to the Webset Items."""
400
+ metadata: Optional[Dict[str, Any]] = None
401
+ """Set of key-value pairs you want to associate with this object."""
402
+ created_at: datetime = Field(..., alias='createdAt')
403
+ """The date and time the webset was created"""
404
+ updated_at: datetime = Field(..., alias='updatedAt')
405
+ """The date and time the webset was updated"""
406
+
407
+
408
+ class WebsetArticleEntity(ExaBaseModel):
409
+ type: Literal['article']
410
+
411
+
412
+ class WebsetCompanyEntity(ExaBaseModel):
413
+ type: Literal['company']
414
+
415
+
416
+ class WebsetCreatedEvent(ExaBaseModel):
417
+ id: str
418
+ """The unique identifier for the event"""
419
+ object: Literal['event']
420
+ type: Literal['webset.created']
421
+ data: Webset
422
+ created_at: datetime = Field(..., alias='createdAt')
423
+ """The date and time the event was created"""
424
+
425
+
426
+ class WebsetCustomEntity(ExaBaseModel):
427
+ type: Literal['custom']
428
+ description: constr(min_length=2, max_length=200)
429
+ """When you decide to use a custom entity, this is the description of the entity."""
430
+
431
+
432
+ class WebsetDeletedEvent(ExaBaseModel):
433
+ id: str
434
+ """The unique identifier for the event"""
435
+ object: Literal['event']
436
+ type: Literal['webset.deleted']
437
+ data: Webset
438
+ created_at: datetime = Field(..., alias='createdAt')
439
+ """The date and time the event was created"""
440
+
441
+
442
+ class WebsetEnrichment(ExaBaseModel):
443
+ id: str
444
+ """The unique identifier for the enrichment"""
445
+ object: Literal['webset_enrichment']
446
+ status: WebsetEnrichmentStatus = Field(..., title='WebsetEnrichmentStatus')
447
+ """The status of the enrichment"""
448
+ webset_id: str = Field(..., alias='websetId')
449
+ """The unique identifier for the Webset this enrichment belongs to."""
450
+ title: Optional[str] = None
451
+ """The title of the enrichment."""
452
+ description: str
453
+ """The description of the enrichment task provided during the creation of the enrichment."""
454
+ format: Optional[WebsetEnrichmentFormat]
455
+ """The format of the enrichment response."""
456
+ options: Optional[List[WebsetEnrichmentOption]] = Field(
457
+ ..., title='WebsetEnrichmentOptions'
458
+ )
459
+ """When the format is options, the different options for the enrichment agent to choose from."""
460
+ instructions: Optional[str] = None
461
+ """The instructions for the enrichment Agent."""
462
+ metadata: Optional[Dict[str, Any]] = None
463
+ """The metadata of the enrichment"""
464
+ created_at: datetime = Field(..., alias='createdAt')
465
+ """The date and time the enrichment was created"""
466
+ updated_at: datetime = Field(..., alias='updatedAt')
467
+ """The date and time the enrichment was updated"""
468
+
469
+
470
+ class WebsetEnrichmentFormat(Enum):
471
+ text = 'text'
472
+ date = 'date'
473
+ number = 'number'
474
+ options = 'options'
475
+ email = 'email'
476
+ phone = 'phone'
477
+
478
+
479
+ class WebsetEnrichmentOption(Option):
480
+ pass
481
+
482
+
483
+ class WebsetEnrichmentStatus(Enum):
484
+ """The status of the enrichment"""
485
+ pending = 'pending'
486
+ canceled = 'canceled'
487
+ completed = 'completed'
488
+
489
+
490
+ class WebsetExportFormat(Enum):
491
+ csv = 'csv'
492
+
493
+
494
+ class WebsetIdleEvent(ExaBaseModel):
495
+ id: str
496
+ """The unique identifier for the event"""
497
+ object: Literal['event']
498
+ type: Literal['webset.idle']
499
+ data: Webset
500
+ created_at: datetime = Field(..., alias='createdAt')
501
+ """The date and time the event was created"""
502
+
503
+
504
+ class WebsetItem(ExaBaseModel):
505
+ id: str
506
+ """The unique identifier for the Webset Item"""
507
+ object: Literal['webset_item']
508
+ source: Source
509
+ """The source of the Item"""
510
+ source_id: str = Field(..., alias='sourceId')
511
+ """The unique identifier for the source"""
512
+ webset_id: str = Field(..., alias='websetId')
513
+ """The unique identifier for the Webset this Item belongs to."""
514
+ properties: Union[
515
+ WebsetItemPersonProperties,
516
+ WebsetItemCompanyProperties,
517
+ WebsetItemArticleProperties,
518
+ WebsetItemResearchPaperProperties,
519
+ WebsetItemCustomProperties,
520
+ ]
521
+ """The properties of the Item"""
522
+ evaluations: List[WebsetItemEvaluation]
523
+ """The criteria evaluations of the item"""
524
+ enrichments: Optional[List[EnrichmentResult]]
525
+ """The enrichments results of the Webset item"""
526
+ created_at: datetime = Field(..., alias='createdAt')
527
+ """The date and time the item was created"""
528
+ updated_at: datetime = Field(..., alias='updatedAt')
529
+ """The date and time the item was last updated"""
530
+
531
+
532
+ class WebsetItemArticleProperties(ExaBaseModel):
533
+ type: Literal['article']
534
+ url: AnyUrl
535
+ """The URL of the article"""
536
+ description: str
537
+ """Short description of the relevance of the article"""
538
+ content: Optional[str] = None
539
+ """The text content for the article"""
540
+ article: WebsetItemArticlePropertiesFields = Field(
541
+ ..., title='WebsetItemArticlePropertiesFields'
542
+ )
543
+
544
+
545
+ class WebsetItemArticlePropertiesFields(ExaBaseModel):
546
+ author: Optional[str] = None
547
+ """The author(s) of the article"""
548
+ published_at: Optional[str] = Field(..., alias='publishedAt')
549
+ """The date and time the article was published"""
550
+
551
+
552
+ class WebsetItemCompanyProperties(ExaBaseModel):
553
+ type: Literal['company']
554
+ url: AnyUrl
555
+ """The URL of the company website"""
556
+ description: str
557
+ """Short description of the relevance of the company"""
558
+ content: Optional[str] = None
559
+ """The text content of the company website"""
560
+ company: WebsetItemCompanyPropertiesFields = Field(
561
+ ..., title='WebsetItemCompanyPropertiesFields'
562
+ )
563
+
564
+
565
+ class WebsetItemCompanyPropertiesFields(ExaBaseModel):
566
+ name: str
567
+ """The name of the company"""
568
+ location: Optional[str] = None
569
+ """The main location of the company"""
570
+ employees: Optional[float] = None
571
+ """The number of employees of the company"""
572
+ industry: Optional[str] = None
573
+ """The industry of the company"""
574
+ about: Optional[str] = None
575
+ """A short description of the company"""
576
+ logo_url: Optional[AnyUrl] = Field(..., alias='logoUrl')
577
+ """The logo URL of the company"""
578
+
579
+
580
+ class WebsetItemCreatedEvent(ExaBaseModel):
581
+ id: str
582
+ """The unique identifier for the event"""
583
+ object: Literal['event']
584
+ type: Literal['webset.item.created']
585
+ data: WebsetItem
586
+ created_at: datetime = Field(..., alias='createdAt')
587
+ """The date and time the event was created"""
588
+
589
+
590
+ class WebsetItemCustomProperties(ExaBaseModel):
591
+ type: Literal['custom']
592
+ url: AnyUrl
593
+ """The URL of the Item"""
594
+ description: str
595
+ """Short description of the Item"""
596
+ content: Optional[str] = None
597
+ """The text content of the Item"""
598
+ custom: WebsetItemCustomPropertiesFields = Field(
599
+ ..., title='WebsetItemCustomPropertiesFields'
600
+ )
601
+
602
+
603
+ class WebsetItemCustomPropertiesFields(ExaBaseModel):
604
+ author: Optional[str] = None
605
+ """The author(s) of the website"""
606
+ published_at: Optional[str] = Field(..., alias='publishedAt')
607
+ """The date and time the website was published"""
608
+
609
+
610
+ class WebsetItemEnrichedEvent(ExaBaseModel):
611
+ id: str
612
+ """The unique identifier for the event"""
613
+ object: Literal['event']
614
+ type: Literal['webset.item.enriched']
615
+ data: WebsetItem
616
+ created_at: datetime = Field(..., alias='createdAt')
617
+ """The date and time the event was created"""
618
+
619
+
620
+ class WebsetItemEvaluation(ExaBaseModel):
621
+ criterion: str
622
+ """The description of the criterion"""
623
+ reasoning: str
624
+ """The reasoning for the result of the evaluation"""
625
+ satisfied: Satisfied
626
+ """The satisfaction of the criterion"""
627
+ references: Optional[List[Reference]]
628
+ """The references used to generate the result. `null` if the evaluation is not yet completed."""
629
+
630
+
631
+ class WebsetItemPersonProperties(ExaBaseModel):
632
+ type: Literal['person']
633
+ url: AnyUrl
634
+ """The URL of the person profile"""
635
+ description: str
636
+ """Short description of the relevance of the person"""
637
+ person: WebsetItemPersonPropertiesFields = Field(
638
+ ..., title='WebsetItemPersonPropertiesFields'
639
+ )
640
+
641
+
642
+ class WebsetItemPersonPropertiesFields(ExaBaseModel):
643
+ name: str
644
+ """The name of the person"""
645
+ location: Optional[str] = None
646
+ """The location of the person"""
647
+ position: Optional[str] = None
648
+ """The current work position of the person"""
649
+ picture_url: Optional[AnyUrl] = Field(..., alias='pictureUrl')
650
+ """The image URL of the person"""
651
+
652
+
653
+ class WebsetItemResearchPaperProperties(ExaBaseModel):
654
+ type: Literal['research_paper']
655
+ url: AnyUrl
656
+ """The URL of the research paper"""
657
+ description: str
658
+ """Short description of the relevance of the research paper"""
659
+ content: Optional[str] = None
660
+ """The text content of the research paper"""
661
+ research_paper: WebsetItemResearchPaperPropertiesFields = Field(
662
+ ..., alias='researchPaper', title='WebsetItemResearchPaperPropertiesFields'
663
+ )
664
+
665
+
666
+ class WebsetItemResearchPaperPropertiesFields(ExaBaseModel):
667
+ author: Optional[str] = None
668
+ """The author(s) of the research paper"""
669
+ published_at: Optional[str] = Field(..., alias='publishedAt')
670
+ """The date and time the research paper was published"""
671
+
672
+
673
+ class WebsetPausedEvent(ExaBaseModel):
674
+ id: str
675
+ """The unique identifier for the event"""
676
+ object: Literal['event']
677
+ type: Literal['webset.paused']
678
+ data: Webset
679
+ created_at: datetime = Field(..., alias='createdAt')
680
+ """The date and time the event was created"""
681
+
682
+
683
+ class WebsetPersonEntity(ExaBaseModel):
684
+ type: Literal['person']
685
+
686
+
687
+ class WebsetResearchPaperEntity(ExaBaseModel):
688
+ type: Literal['research_paper']
689
+
690
+
691
+ class WebsetSearch(ExaBaseModel):
692
+ id: str
693
+ """The unique identifier for the search"""
694
+ object: Literal['webset_search']
695
+ status: WebsetSearchStatus = Field(..., title='WebsetSearchStatus')
696
+ """The status of the search"""
697
+ query: constr(min_length=1, max_length=5000)
698
+ """The query used to create the search."""
699
+ entity: Optional[
700
+ Union[
701
+ WebsetCompanyEntity,
702
+ WebsetPersonEntity,
703
+ WebsetArticleEntity,
704
+ WebsetResearchPaperEntity,
705
+ WebsetCustomEntity,
706
+ ]
707
+ ]
708
+ """The entity the search will return results for."""
709
+ criteria: List[Criterion]
710
+ """The criteria the search will use to evaluate the results."""
711
+ count: confloat(ge=1.0)
712
+ """The number of results the search will attempt to find."""
713
+ progress: Progress
714
+ """The progress of the search"""
715
+ metadata: Optional[Dict[str, Any]] = None
716
+ """Set of key-value pairs you want to associate with this object."""
717
+ canceled_at: Optional[datetime] = Field(..., alias='canceledAt')
718
+ """The date and time the search was canceled"""
719
+ canceled_reason: Optional[CanceledReason] = Field(..., alias='canceledReason')
720
+ """The reason the search was canceled"""
721
+ created_at: datetime = Field(..., alias='createdAt')
722
+ """The date and time the search was created"""
723
+ updated_at: datetime = Field(..., alias='updatedAt')
724
+ """The date and time the search was updated"""
725
+
726
+
727
+ class WebsetSearchBehaviour(Enum):
728
+ """The behaviour of the Search when it is added to a Webset."""
729
+ override = 'override'
730
+
731
+
732
+ class WebsetSearchCanceledEvent(ExaBaseModel):
733
+ id: str
734
+ """The unique identifier for the event"""
735
+ object: Literal['event']
736
+ type: Literal['webset.search.canceled']
737
+ data: WebsetSearch
738
+ created_at: datetime = Field(..., alias='createdAt')
739
+ """The date and time the event was created"""
740
+
741
+
742
+ class WebsetSearchCompletedEvent(ExaBaseModel):
743
+ id: str
744
+ """The unique identifier for the event"""
745
+ object: Literal['event']
746
+ type: Literal['webset.search.completed']
747
+ data: WebsetSearch
748
+ created_at: datetime = Field(..., alias='createdAt')
749
+ """The date and time the event was created"""
750
+
751
+
752
+ class WebsetSearchCreatedEvent(ExaBaseModel):
753
+ id: str
754
+ """The unique identifier for the event"""
755
+ object: Literal['event']
756
+ type: Literal['webset.search.created']
757
+ data: WebsetSearch
758
+ created_at: datetime = Field(..., alias='createdAt')
759
+ """The date and time the event was created"""
760
+
761
+
762
+ class WebsetSearchStatus(Enum):
763
+ """The status of the search"""
764
+ created = 'created'
765
+ running = 'running'
766
+ completed = 'completed'
767
+ canceled = 'canceled'
768
+
769
+
770
+ class WebsetSearchUpdatedEvent(ExaBaseModel):
771
+ id: str
772
+ """The unique identifier for the event"""
773
+ object: Literal['event']
774
+ type: Literal['webset.search.updated']
775
+ data: WebsetSearch
776
+ created_at: datetime = Field(..., alias='createdAt')
777
+ """The date and time the event was created"""
778
+
779
+
780
+ class WebsetStatus(Enum):
781
+ """The status of the webset"""
782
+ idle = 'idle'
783
+ running = 'running'
784
+ paused = 'paused'
785
+
786
+
787
+ class GetWebsetResponse(Webset):
788
+ items: Optional[List[WebsetItem]] = None
789
+ """When expand query parameter contains `items`, this will contain the items in the webset"""
790
+
791
+ ################################
792
+ # Items Client (items/client.py)
793
+ ################################
794
+
795
+ from __future__ import annotations
796
+
797
+ from typing import Optional, Iterator
798
+
799
+ from ..types import (
800
+ WebsetItem,
801
+ ListWebsetItemResponse,
802
+ )
803
+ from ..core.base import WebsetsBaseClient
804
+
805
+ class WebsetItemsClient(WebsetsBaseClient):
806
+ """Client for managing Webset Items."""
807
+
808
+ def __init__(self, client):
809
+ super().__init__(client)
810
+
811
+ def list(self, webset_id: str, *, cursor: Optional[str] = None,
812
+ limit: Optional[int] = None) -> ListWebsetItemResponse:
813
+ """List all Items for a Webset."""
814
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit}.items() if v is not None}
815
+ response = self.request(f"/v0/websets/{webset_id}/items", params=params, method="GET")
816
+ return ListWebsetItemResponse.model_validate(response)
817
+
818
+ def list_all(self, webset_id: str, *, limit: Optional[int] = None) -> Iterator[WebsetItem]:
819
+ """Iterate through all Items in a Webset, handling pagination automatically."""
820
+ cursor = None
821
+ while True:
822
+ response = self.list(webset_id, cursor=cursor, limit=limit)
823
+ for item in response.data:
824
+ yield item
825
+
826
+ if not response.has_more or not response.next_cursor:
827
+ break
828
+
829
+ cursor = response.next_cursor
830
+
831
+ def get(self, webset_id: str, id: str) -> WebsetItem:
832
+ """Get an Item by ID."""
833
+ response = self.request(f"/v0/websets/{webset_id}/items/{id}", method="GET")
834
+ return WebsetItem.model_validate(response)
835
+
836
+ def delete(self, webset_id: str, id: str) -> WebsetItem:
837
+ """Delete an Item."""
838
+ response = self.request(f"/v0/websets/{webset_id}/items/{id}", method="DELETE")
839
+ return WebsetItem.model_validate(response)
840
+
841
+ ################################
842
+ # Searches Client (searches/client.py)
843
+ ################################
844
+
845
+ from __future__ import annotations
846
+
847
+ from ..types import (
848
+ CreateWebsetSearchParameters,
849
+ WebsetSearch,
850
+ )
851
+ from ..core.base import WebsetsBaseClient
852
+
853
+ class WebsetSearchesClient(WebsetsBaseClient):
854
+ """Client for managing Webset Searches."""
855
+
856
+ def __init__(self, client):
857
+ super().__init__(client)
858
+
859
+ def create(self, webset_id: str, params: CreateWebsetSearchParameters) -> WebsetSearch:
860
+ """Create a new Search for the Webset."""
861
+ response = self.request(f"/v0/websets/{webset_id}/searches", data=params.model_dump(by_alias=True, exclude_none=True))
862
+ return WebsetSearch.model_validate(response)
863
+
864
+ def get(self, webset_id: str, id: str) -> WebsetSearch:
865
+ """Get a Search by ID."""
866
+ response = self.request(f"/v0/websets/{webset_id}/searches/{id}", method="GET")
867
+ return WebsetSearch.model_validate(response)
868
+
869
+ def cancel(self, webset_id: str, id: str) -> WebsetSearch:
870
+ """Cancel a running Search."""
871
+ response = self.request(f"/v0/websets/{webset_id}/searches/{id}/cancel", method="POST")
872
+ return WebsetSearch.model_validate(response)
873
+
874
+ ################################
875
+ # Enrichments Client (enrichments/client.py)
876
+ ################################
877
+
878
+ from __future__ import annotations
879
+
880
+ from ..types import (
881
+ CreateEnrichmentParameters,
882
+ WebsetEnrichment,
883
+ )
884
+ from ..core.base import WebsetsBaseClient
885
+
886
+ class WebsetEnrichmentsClient(WebsetsBaseClient):
887
+ """Client for managing Webset Enrichments."""
888
+
889
+ def __init__(self, client):
890
+ super().__init__(client)
891
+
892
+ def create(self, webset_id: str, params: CreateEnrichmentParameters) -> WebsetEnrichment:
893
+ """Create an Enrichment for a Webset."""
894
+ response = self.request(f"/v0/websets/{webset_id}/enrichments", data=params.model_dump(by_alias=True, exclude_none=True))
895
+ return WebsetEnrichment.model_validate(response)
896
+
897
+ def get(self, webset_id: str, id: str) -> WebsetEnrichment:
898
+ """Get an Enrichment by ID."""
899
+ response = self.request(f"/v0/websets/{webset_id}/enrichments/{id}", method="GET")
900
+ return WebsetEnrichment.model_validate(response)
901
+
902
+ def delete(self, webset_id: str, id: str) -> WebsetEnrichment:
903
+ """Delete an Enrichment."""
904
+ response = self.request(f"/v0/websets/{webset_id}/enrichments/{id}", method="DELETE")
905
+ return WebsetEnrichment.model_validate(response)
906
+
907
+ def cancel(self, webset_id: str, id: str) -> WebsetEnrichment:
908
+ """Cancel a running Enrichment."""
909
+ response = self.request(f"/v0/websets/{webset_id}/enrichments/{id}/cancel", method="POST")
910
+ return WebsetEnrichment.model_validate(response)
911
+
912
+ ################################
913
+ # Webhooks Client (webhooks/client.py)
914
+ ################################
915
+
916
+ from __future__ import annotations
917
+
918
+ from typing import Optional
919
+
920
+ from ..types import (
921
+ CreateWebhookParameters,
922
+ Webhook,
923
+ ListWebhooksResponse,
924
+ UpdateWebhookParameters,
925
+ )
926
+ from ..core.base import WebsetsBaseClient
927
+
928
+ class WebsetWebhooksClient(WebsetsBaseClient):
929
+ """Client for managing Webset Webhooks."""
930
+
931
+ def __init__(self, client):
932
+ super().__init__(client)
933
+
934
+ def create(self, params: CreateWebhookParameters) -> Webhook:
935
+ """Create a Webhook."""
936
+ response = self.request("/v0/webhooks", data=params.model_dump(by_alias=True, exclude_none=True))
937
+ return Webhook.model_validate(response)
938
+
939
+ def get(self, id: str) -> Webhook:
940
+ """Get a Webhook by ID."""
941
+ response = self.request(f"/v0/webhooks/{id}", method="GET")
942
+ return Webhook.model_validate(response)
943
+
944
+ def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None) -> ListWebhooksResponse:
945
+ """List all Webhooks."""
946
+ params = {k: v for k, v in {"cursor": cursor, "limit": limit}.items() if v is not None}
947
+ response = self.request("/v0/webhooks", params=params, method="GET")
948
+ return ListWebhooksResponse.model_validate(response)
949
+
950
+ def update(self, id: str, params: UpdateWebhookParameters) -> Webhook:
951
+ """Update a Webhook."""
952
+ response = self.request(f"/v0/webhooks/{id}", data=params.model_dump(by_alias=True, exclude_none=True), method="PATCH")
953
+ return Webhook.model_validate(response)
954
+
955
+ def delete(self, id: str) -> Webhook:
956
+ """Delete a Webhook."""
957
+ response = self.request(f"/v0/webhooks/{id}", method="DELETE")
958
+ return Webhook.model_validate(response)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exa-py
3
- Version: 1.10.0
3
+ Version: 1.11.0
4
4
  Summary: Python SDK for Exa API.
5
5
  License: MIT
6
6
  Author: Exa AI
@@ -1,5 +1,5 @@
1
1
  exa_py/__init__.py,sha256=M2GC9oSdoV6m2msboW0vMWWl8wrth4o6gmEV4MYLGG8,66
2
- exa_py/api.py,sha256=LZMOw4bu-h0J6wptXNHHgK2O5NvMOL5O9F2JjuK0qYU,82559
2
+ exa_py/api.py,sha256=u9HjGGqN3yzWjXiWE79OW630zA01TzO99iprAeWHOhQ,83244
3
3
  exa_py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  exa_py/utils.py,sha256=Rc1FJjoR9LQ7L_OJM91Sd1GNkbHjcLyEvJENhRix6gc,2405
5
5
  exa_py/websets/__init__.py,sha256=uOBAb9VrIHrPKoddGOp2ai2KgWlyUVCLMZqfbGOlboA,70
@@ -16,6 +16,7 @@ exa_py/websets/searches/client.py,sha256=elDZxycmKToOPU-F2utP2ia9x5m68vEu_5ymypc
16
16
  exa_py/websets/types.py,sha256=njlUgvZJab8hg2_6tqYa5SYvuYowDNKP9MKrmV2PSq0,26559
17
17
  exa_py/websets/webhooks/__init__.py,sha256=iTPBCxFd73z4RifLQMX6iRECx_6pwlI5qscLNjMOUHE,77
18
18
  exa_py/websets/webhooks/client.py,sha256=jNNFzUoWXW9KOswNrZ32LUO1gSbA89XBWyQkyLrUAuE,2664
19
- exa_py-1.10.0.dist-info/METADATA,sha256=DcDqL0AeY0uPA4mDy6JPuQ9I2EJDDzqqCYXpFYl3rCg,3565
20
- exa_py-1.10.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
21
- exa_py-1.10.0.dist-info/RECORD,,
19
+ exa_py/websets/websets_one_file.txt,sha256=u12CY0G5vqA3AzjQnotWfD9f0affhvtU-Tzir51v3aQ,33007
20
+ exa_py-1.11.0.dist-info/METADATA,sha256=G46FhO3UNnF2cQj5aQkzsqrBIPhl70yFKE66uZEQ2dw,3565
21
+ exa_py-1.11.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
22
+ exa_py-1.11.0.dist-info/RECORD,,