exa-py 1.11.0__tar.gz → 1.12.0__tar.gz

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.

Files changed (23) hide show
  1. {exa_py-1.11.0 → exa_py-1.12.0}/PKG-INFO +1 -1
  2. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/api.py +24 -7
  3. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/client.py +23 -17
  4. exa_py-1.12.0/exa_py/websets/core/base.py +96 -0
  5. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/enrichments/client.py +4 -2
  6. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/searches/client.py +4 -2
  7. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/types.py +92 -30
  8. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/webhooks/client.py +44 -6
  9. {exa_py-1.11.0 → exa_py-1.12.0}/pyproject.toml +2 -2
  10. exa_py-1.11.0/exa_py/websets/core/base.py +0 -41
  11. exa_py-1.11.0/exa_py/websets/websets_one_file.txt +0 -958
  12. {exa_py-1.11.0 → exa_py-1.12.0}/README.md +0 -0
  13. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/__init__.py +0 -0
  14. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/py.typed +0 -0
  15. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/utils.py +0 -0
  16. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/__init__.py +0 -0
  17. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/_generator/pydantic/BaseModel.jinja2 +0 -0
  18. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/core/__init__.py +0 -0
  19. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/enrichments/__init__.py +0 -0
  20. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/items/__init__.py +0 -0
  21. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/items/client.py +0 -0
  22. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/searches/__init__.py +0 -0
  23. {exa_py-1.11.0 → exa_py-1.12.0}/exa_py/websets/webhooks/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: exa-py
3
- Version: 1.11.0
3
+ Version: 1.12.0
4
4
  Summary: Python SDK for Exa API.
5
5
  License: MIT
6
6
  Author: Exa AI
@@ -7,6 +7,7 @@ import re
7
7
  from dataclasses import dataclass
8
8
  from functools import wraps
9
9
  from typing import (
10
+ Any,
10
11
  Callable,
11
12
  Dict,
12
13
  Generic,
@@ -36,6 +37,7 @@ from exa_py.utils import (
36
37
  maybe_get_query,
37
38
  )
38
39
  from .websets import WebsetsClient
40
+ from .websets.core.base import ExaJSONEncoder
39
41
 
40
42
  is_beta = os.getenv("IS_BETA") == "True"
41
43
 
@@ -840,7 +842,7 @@ class Exa:
840
842
  self,
841
843
  api_key: Optional[str],
842
844
  base_url: str = "https://api.exa.ai",
843
- user_agent: str = "exa-py 1.11.0",
845
+ user_agent: str = "exa-py 1.12.0",
844
846
  ):
845
847
  """Initialize the Exa client with the provided API key and optional base URL and user agent.
846
848
 
@@ -857,17 +859,17 @@ class Exa:
857
859
  "API key must be provided as an argument or in EXA_API_KEY environment variable"
858
860
  )
859
861
  self.base_url = base_url
860
- self.headers = {"x-api-key": api_key, "User-Agent": user_agent}
862
+ self.headers = {"x-api-key": api_key, "User-Agent": user_agent, "Content-Type": "application/json"}
861
863
  self.websets = WebsetsClient(self)
862
864
 
863
- def request(self, endpoint: str, data=None, method="POST", params=None):
865
+ def request(self, endpoint: str, data: Optional[Union[Dict[str, Any], str]] = None, method: str = "POST", params: Optional[Dict[str, Any]] = None) -> Union[Dict[str, Any], requests.Response]:
864
866
  """Send a request to the Exa API, optionally streaming if data['stream'] is True.
865
867
 
866
868
  Args:
867
869
  endpoint (str): The API endpoint (path).
868
870
  data (dict, optional): The JSON payload to send. Defaults to None.
869
871
  method (str, optional): The HTTP method to use. Defaults to "POST".
870
- params (dict, optional): Query parameters to include. Defaults to None.
872
+ params (Dict[str, Any], optional): Query parameters to include. Defaults to None.
871
873
 
872
874
  Returns:
873
875
  Union[dict, requests.Response]: If streaming, returns the Response object.
@@ -876,9 +878,20 @@ class Exa:
876
878
  Raises:
877
879
  ValueError: If the request fails (non-200 status code).
878
880
  """
881
+ # Handle the case when data is a string
882
+ if isinstance(data, str):
883
+ # Use the string directly as the data payload
884
+ json_data = data
885
+ else:
886
+ # Otherwise, serialize the dictionary to JSON if it exists
887
+ json_data = json.dumps(data, cls=ExaJSONEncoder) if data else None
888
+
879
889
  if data and data.get("stream"):
880
890
  res = requests.post(
881
- self.base_url + endpoint, json=data, headers=self.headers, stream=True
891
+ self.base_url + endpoint,
892
+ data=json_data,
893
+ headers=self.headers,
894
+ stream=True
882
895
  )
883
896
  return res
884
897
 
@@ -888,11 +901,15 @@ class Exa:
888
901
  )
889
902
  elif method.upper() == "POST":
890
903
  res = requests.post(
891
- self.base_url + endpoint, json=data, headers=self.headers
904
+ self.base_url + endpoint,
905
+ data=json_data,
906
+ headers=self.headers
892
907
  )
893
908
  elif method.upper() == "PATCH":
894
909
  res = requests.patch(
895
- self.base_url + endpoint, json=data, headers=self.headers
910
+ self.base_url + endpoint,
911
+ data=json_data,
912
+ headers=self.headers
896
913
  )
897
914
  elif method.upper() == "DELETE":
898
915
  res = requests.delete(
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import time
4
4
  from datetime import datetime
5
- from typing import List, Optional, Literal
5
+ from typing import List, Optional, Literal, Dict, Any, Union
6
6
 
7
7
  from .types import (
8
8
  Webset,
@@ -28,16 +28,16 @@ class WebsetsClient(WebsetsBaseClient):
28
28
  self.enrichments = WebsetEnrichmentsClient(client)
29
29
  self.webhooks = WebsetWebhooksClient(client)
30
30
 
31
- def create(self, params: CreateWebsetParameters) -> Webset:
31
+ def create(self, params: Union[Dict[str, Any], CreateWebsetParameters]) -> Webset:
32
32
  """Create a new Webset.
33
33
 
34
34
  Args:
35
- params (CreateWebsetRequest): The parameters for creating a webset.
35
+ params (CreateWebsetParameters): The parameters for creating a webset.
36
36
 
37
37
  Returns:
38
38
  Webset: The created webset.
39
39
  """
40
- response = self.request("/v0/websets", data=params.model_dump(by_alias=True, exclude_none=True))
40
+ response = self.request("/v0/websets", data=params)
41
41
  return Webset.model_validate(response)
42
42
 
43
43
  def get(self, id: str, *, expand: Optional[List[Literal["items"]]] = None) -> GetWebsetResponse:
@@ -69,7 +69,7 @@ class WebsetsClient(WebsetsBaseClient):
69
69
  response = self.request("/v0/websets", params=params, method="GET")
70
70
  return ListWebsetsResponse.model_validate(response)
71
71
 
72
- def update(self, id: str, params: UpdateWebsetRequest) -> Webset:
72
+ def update(self, id: str, params: Union[Dict[str, Any], UpdateWebsetRequest]) -> Webset:
73
73
  """Update a Webset.
74
74
 
75
75
  Args:
@@ -79,7 +79,7 @@ class WebsetsClient(WebsetsBaseClient):
79
79
  Returns:
80
80
  Webset: The updated webset.
81
81
  """
82
- response = self.request(f"/v0/websets/{id}", data=params.model_dump(by_alias=True, exclude_none=True), method="POST")
82
+ response = self.request(f"/v0/websets/{id}", data=params, method="POST")
83
83
  return Webset.model_validate(response)
84
84
 
85
85
  def delete(self, id: str) -> Webset:
@@ -104,23 +104,29 @@ class WebsetsClient(WebsetsBaseClient):
104
104
  Webset: The canceled webset.
105
105
  """
106
106
  response = self.request(f"/v0/websets/{id}/cancel", method="POST")
107
- return Webset.model_validate(response)
108
-
109
- def wait_until_idle(self, id: str, *, timeout: Optional[int] = None) -> Webset:
107
+ return Webset.model_validate(response)
108
+
109
+ def wait_until_idle(self, id: str, *, timeout: int = 3600, poll_interval: int = 5) -> Webset:
110
110
  """Wait until a Webset is idle.
111
111
 
112
112
  Args:
113
113
  id (str): The id or externalId of the Webset.
114
-
114
+ timeout (int, optional): Maximum time to wait in seconds. Defaults to 3600.
115
+ poll_interval (int, optional): Time to wait between polls in seconds. Defaults to 5.
116
+
115
117
  Returns:
116
- Webset: The webset.
118
+ Webset: The webset once it's idle.
119
+
120
+ Raises:
121
+ TimeoutError: If the webset does not become idle within the timeout period.
117
122
  """
118
123
  start_time = time.time()
119
124
  while True:
120
125
  webset = self.get(id)
121
- if webset.status == WebsetStatus.idle:
122
- break
123
- time.sleep(1)
124
- if timeout and time.time() - start_time > timeout:
125
- raise Exception("Webset timed out")
126
- return webset
126
+ if webset.status == WebsetStatus.idle.value:
127
+ return webset
128
+
129
+ if time.time() - start_time > timeout:
130
+ raise TimeoutError(f"Webset {id} did not become idle within {timeout} seconds")
131
+
132
+ time.sleep(poll_interval)
@@ -0,0 +1,96 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pydantic import ConfigDict, BaseModel, AnyUrl
5
+ from enum import Enum
6
+ from typing import Any, Dict, Optional, TypeVar, Generic, Type, get_origin, get_args, Union
7
+
8
+ # Generic type var for any Enum
9
+ EnumT = TypeVar('EnumT', bound=Enum)
10
+
11
+ # Generic type for any ExaBaseModel
12
+ ModelT = TypeVar('ModelT', bound='ExaBaseModel')
13
+
14
+ # Custom JSON encoder for handling AnyUrl
15
+ class ExaJSONEncoder(json.JSONEncoder):
16
+ def default(self, obj):
17
+ if isinstance(obj, AnyUrl):
18
+ return str(obj)
19
+ return super().default(obj)
20
+
21
+ class ExaBaseModel(BaseModel):
22
+ """Base model for all Exa models with common configuration."""
23
+ model_config = ConfigDict(
24
+ populate_by_name=True,
25
+ use_enum_values=True,
26
+ coerce_numbers_to_str=False, # Don't convert numbers to strings
27
+ str_strip_whitespace=True, # Strip whitespace from strings
28
+ str_to_lower=False, # Don't convert strings to lowercase
29
+ str_to_upper=False, # Don't convert strings to uppercase
30
+ from_attributes=True, # Allow initialization from attributes
31
+ validate_assignment=True, # Validate on assignment
32
+ extra='forbid', # Forbid extra fields
33
+ json_encoders={AnyUrl: str} # Convert AnyUrl to string when serializing to JSON
34
+ )
35
+
36
+ class WebsetsBaseClient:
37
+ base_url: str
38
+
39
+ """Base client for Exa API resources."""
40
+
41
+ def __init__(self, client):
42
+ """Initialize the client.
43
+
44
+ Args:
45
+ client: The parent Exa client.
46
+ """
47
+ self._client = client
48
+
49
+ def _prepare_data(self, data: Union[Dict[str, Any], ExaBaseModel, str], model_class: Optional[Type[ModelT]] = None) -> Union[Dict[str, Any], str]:
50
+ """Prepare data for API request, converting dict to model if needed.
51
+
52
+ Args:
53
+ data: Either a dictionary, model instance, or string
54
+ model_class: The model class to use if data is a dictionary
55
+
56
+ Returns:
57
+ Dictionary prepared for API request or string if string data was provided
58
+ """
59
+ if isinstance(data, str):
60
+ # Return string as is
61
+ return data
62
+ elif isinstance(data, dict) and model_class:
63
+ # Convert dict to model instance
64
+ model_instance = model_class.model_validate(data)
65
+ return model_instance.model_dump(by_alias=True, exclude_none=True)
66
+ elif isinstance(data, ExaBaseModel):
67
+ # Use model's dump method
68
+ return data.model_dump(by_alias=True, exclude_none=True)
69
+ elif isinstance(data, dict):
70
+ # Use dict directly
71
+ return data
72
+ else:
73
+ raise TypeError(f"Expected dict, ExaBaseModel, or str, got {type(data)}")
74
+
75
+ def request(self, endpoint: str, data: Optional[Union[Dict[str, Any], ExaBaseModel, str]] = None,
76
+ method: str = "POST", params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
77
+ """Make a request to the Exa API.
78
+
79
+ Args:
80
+ endpoint (str): The API endpoint to request.
81
+ data (Union[Dict[str, Any], ExaBaseModel, str], optional): The request data. Can be a dictionary, model instance, or string. Defaults to None.
82
+ method (str, optional): The HTTP method. Defaults to "POST".
83
+ params (Dict[str, Any], optional): The query parameters. Defaults to None.
84
+
85
+ Returns:
86
+ Dict[str, Any]: The API response.
87
+ """
88
+ if isinstance(data, str):
89
+ # If data is a string, pass it as is
90
+ pass
91
+ elif data is not None and isinstance(data, ExaBaseModel):
92
+ # If data is a model instance, convert it to a dict
93
+ data = data.model_dump(by_alias=True, exclude_none=True)
94
+
95
+ return self._client.request("/websets/" + endpoint, data=data, method=method, params=params)
96
+
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Dict, Any, Union
4
+
3
5
  from ..types import (
4
6
  CreateEnrichmentParameters,
5
7
  WebsetEnrichment,
@@ -12,7 +14,7 @@ class WebsetEnrichmentsClient(WebsetsBaseClient):
12
14
  def __init__(self, client):
13
15
  super().__init__(client)
14
16
 
15
- def create(self, webset_id: str, params: CreateEnrichmentParameters) -> WebsetEnrichment:
17
+ def create(self, webset_id: str, params: Union[Dict[str, Any], CreateEnrichmentParameters]) -> WebsetEnrichment:
16
18
  """Create an Enrichment for a Webset.
17
19
 
18
20
  Args:
@@ -22,7 +24,7 @@ class WebsetEnrichmentsClient(WebsetsBaseClient):
22
24
  Returns:
23
25
  WebsetEnrichment: The created enrichment.
24
26
  """
25
- response = self.request(f"/v0/websets/{webset_id}/enrichments", data=params.model_dump(by_alias=True, exclude_none=True))
27
+ response = self.request(f"/v0/websets/{webset_id}/enrichments", data=params)
26
28
  return WebsetEnrichment.model_validate(response)
27
29
 
28
30
  def get(self, webset_id: str, id: str) -> WebsetEnrichment:
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Dict, Any, Union
4
+
3
5
  from ..types import (
4
6
  CreateWebsetSearchParameters,
5
7
  WebsetSearch,
@@ -12,7 +14,7 @@ class WebsetSearchesClient(WebsetsBaseClient):
12
14
  def __init__(self, client):
13
15
  super().__init__(client)
14
16
 
15
- def create(self, webset_id: str, params: CreateWebsetSearchParameters) -> WebsetSearch:
17
+ def create(self, webset_id: str, params: Union[Dict[str, Any], CreateWebsetSearchParameters]) -> WebsetSearch:
16
18
  """Create a new Search for the Webset.
17
19
 
18
20
  Args:
@@ -22,7 +24,7 @@ class WebsetSearchesClient(WebsetsBaseClient):
22
24
  Returns:
23
25
  WebsetSearch: The created search.
24
26
  """
25
- response = self.request(f"/v0/websets/{webset_id}/searches", data=params.model_dump(by_alias=True, exclude_none=True))
27
+ response = self.request(f"/v0/websets/{webset_id}/searches", data=params)
26
28
  return WebsetSearch.model_validate(response)
27
29
 
28
30
  def get(self, webset_id: str, id: str) -> WebsetSearch:
@@ -29,7 +29,7 @@ class CreateEnrichmentParameters(ExaBaseModel):
29
29
  """
30
30
  Provide a description of the enrichment task you want to perform to each Webset Item.
31
31
  """
32
- format: Optional[str] = None
32
+ format: Optional[Format] = None
33
33
  """
34
34
  Format of the enrichment response.
35
35
 
@@ -46,7 +46,7 @@ class CreateEnrichmentParameters(ExaBaseModel):
46
46
 
47
47
 
48
48
  class CreateWebhookParameters(ExaBaseModel):
49
- events: List[Event] = Field(..., max_items=12, min_items=1)
49
+ events: List[EventType] = Field(..., max_items=12, min_items=1)
50
50
  """
51
51
  The events to trigger the webhook
52
52
  """
@@ -127,7 +127,7 @@ class CreateWebsetSearchParameters(ExaBaseModel):
127
127
  """
128
128
  The behaviour of the Search when it is added to a Webset.
129
129
 
130
- - `override`: the search will reuse the existing Items found in the Webset and evaluate them against the new criteria. Any Items that don't match the new criteria will not be discarded.
130
+ - `override`: the search will reuse the existing Items found in the Webset and evaluate them against the new criteria. Any Items that don't match the new criteria will be discarded.
131
131
  """
132
132
  metadata: Optional[Dict[str, Any]] = None
133
133
  """
@@ -149,9 +149,9 @@ class Criterion(ExaBaseModel):
149
149
  class EnrichmentResult(ExaBaseModel):
150
150
  object: Literal['enrichment_result']
151
151
  format: WebsetEnrichmentFormat
152
- result: List[str]
152
+ result: Optional[List[str]] = None
153
153
  """
154
- The result of the enrichment.
154
+ The result of the enrichment. None if the enrichment wasn't successful.
155
155
  """
156
156
  reasoning: Optional[str] = None
157
157
  """
@@ -167,7 +167,7 @@ class EnrichmentResult(ExaBaseModel):
167
167
  """
168
168
 
169
169
 
170
- class Event(Enum):
170
+ class EventType(Enum):
171
171
  webset_created = 'webset.created'
172
172
  webset_deleted = 'webset.deleted'
173
173
  webset_paused = 'webset.paused'
@@ -182,6 +182,7 @@ class Event(Enum):
182
182
  webset_item_enriched = 'webset.item.enriched'
183
183
 
184
184
 
185
+
185
186
  class Format(Enum):
186
187
  """
187
188
  Format of the enrichment response.
@@ -225,6 +226,21 @@ class ListEventsResponse(ExaBaseModel):
225
226
  """
226
227
 
227
228
 
229
+ class ListWebhookAttemptsResponse(ExaBaseModel):
230
+ data: List[WebhookAttempt]
231
+ """
232
+ The list of webhook attempts
233
+ """
234
+ has_more: bool = Field(..., alias='hasMore')
235
+ """
236
+ Whether there are more results to paginate through
237
+ """
238
+ next_cursor: Optional[str] = Field(..., alias='nextCursor')
239
+ """
240
+ The cursor to paginate through the next set of results
241
+ """
242
+
243
+
228
244
  class ListWebhooksResponse(ExaBaseModel):
229
245
  data: List[Webhook]
230
246
  """
@@ -335,7 +351,7 @@ class Search(ExaBaseModel):
335
351
 
336
352
  Any URL provided will be crawled and used as context for the search.
337
353
  """
338
- count: confloat(ge=1.0)
354
+ count: Optional[confloat(ge=1.0)] = 10
339
355
  """
340
356
  Number of Items the Webset will attempt to find.
341
357
 
@@ -374,7 +390,7 @@ class Source(Enum):
374
390
 
375
391
 
376
392
  class UpdateWebhookParameters(ExaBaseModel):
377
- events: Optional[List[Event]] = Field(None, max_items=12, min_items=1)
393
+ events: Optional[List[EventType]] = Field(None, max_items=12, min_items=1)
378
394
  """
379
395
  The events to trigger the webhook
380
396
  """
@@ -389,7 +405,7 @@ class UpdateWebhookParameters(ExaBaseModel):
389
405
 
390
406
 
391
407
  class UpdateWebsetRequest(ExaBaseModel):
392
- metadata: Optional[Dict[str, Any]] = None
408
+ metadata: Optional[Dict[str, constr(max_length=1000)]] = None
393
409
  """
394
410
  Set of key-value pairs you want to associate with this object.
395
411
  """
@@ -405,7 +421,7 @@ class Webhook(ExaBaseModel):
405
421
  """
406
422
  The status of the webhook
407
423
  """
408
- events: List[Event] = Field(..., min_items=1)
424
+ events: List[EventType] = Field(..., min_items=1)
409
425
  """
410
426
  The events to trigger the webhook
411
427
  """
@@ -413,7 +429,11 @@ class Webhook(ExaBaseModel):
413
429
  """
414
430
  The URL to send the webhook to
415
431
  """
416
- metadata: Optional[Dict[str, Any]] = None
432
+ secret: Optional[str] = None
433
+ """
434
+ The secret to verify the webhook signature. Only returned on Webhook creation.
435
+ """
436
+ metadata: Optional[Dict[str, Any]] = {}
417
437
  """
418
438
  The metadata of the webhook
419
439
  """
@@ -427,6 +447,54 @@ class Webhook(ExaBaseModel):
427
447
  """
428
448
 
429
449
 
450
+ class WebhookAttempt(ExaBaseModel):
451
+ id: str
452
+ """
453
+ The unique identifier for the webhook attempt
454
+ """
455
+ object: Literal['webhook_attempt']
456
+ event_id: str = Field(..., alias='eventId')
457
+ """
458
+ The unique identifier for the event
459
+ """
460
+ event_type: EventType = Field(..., alias='eventType')
461
+ """
462
+ The type of event
463
+ """
464
+ webhook_id: str = Field(..., alias='webhookId')
465
+ """
466
+ The unique identifier for the webhook
467
+ """
468
+ url: str
469
+ """
470
+ The URL that was used during the attempt
471
+ """
472
+ successful: bool
473
+ """
474
+ Whether the attempt was successful
475
+ """
476
+ response_headers: Dict[str, Any] = Field(..., alias='responseHeaders')
477
+ """
478
+ The headers of the response
479
+ """
480
+ response_body: str = Field(..., alias='responseBody')
481
+ """
482
+ The body of the response
483
+ """
484
+ response_status_code: float = Field(..., alias='responseStatusCode')
485
+ """
486
+ The status code of the response
487
+ """
488
+ attempt: float
489
+ """
490
+ The attempt number of the webhook
491
+ """
492
+ attempted_at: datetime = Field(..., alias='attemptedAt')
493
+ """
494
+ The date and time the webhook attempt was made
495
+ """
496
+
497
+
430
498
  class WebhookStatus(Enum):
431
499
  """
432
500
  The status of the webhook
@@ -458,7 +526,7 @@ class Webset(ExaBaseModel):
458
526
  """
459
527
  The Enrichments to apply to the Webset Items.
460
528
  """
461
- metadata: Optional[Dict[str, Any]] = None
529
+ metadata: Optional[Dict[str, Any]] = {}
462
530
  """
463
531
  Set of key-value pairs you want to associate with this object.
464
532
  """
@@ -558,7 +626,7 @@ class WebsetEnrichment(ExaBaseModel):
558
626
 
559
627
  This will be automatically generated based on the description and format.
560
628
  """
561
- metadata: Optional[Dict[str, Any]] = None
629
+ metadata: Optional[Dict[str, Any]] = {}
562
630
  """
563
631
  The metadata of the enrichment
564
632
  """
@@ -595,10 +663,6 @@ class WebsetEnrichmentStatus(Enum):
595
663
  completed = 'completed'
596
664
 
597
665
 
598
- class WebsetExportFormat(Enum):
599
- csv = 'csv'
600
-
601
-
602
666
  class WebsetIdleEvent(ExaBaseModel):
603
667
  id: str
604
668
  """
@@ -645,7 +709,7 @@ class WebsetItem(ExaBaseModel):
645
709
  """
646
710
  The criteria evaluations of the item
647
711
  """
648
- enrichments: Optional[List[EnrichmentResult]]
712
+ enrichments: List[EnrichmentResult]
649
713
  """
650
714
  The enrichments results of the Webset item
651
715
  """
@@ -806,7 +870,7 @@ class WebsetItemEvaluation(ExaBaseModel):
806
870
  """
807
871
  The satisfaction of the criterion
808
872
  """
809
- references: Optional[List[Reference]]
873
+ references: List[Reference] = []
810
874
  """
811
875
  The references used to generate the result. `null` if the evaluation is not yet completed.
812
876
  """
@@ -912,14 +976,12 @@ class WebsetSearch(ExaBaseModel):
912
976
  """
913
977
  The query used to create the search.
914
978
  """
915
- entity: Optional[
916
- Union[
917
- WebsetCompanyEntity,
918
- WebsetPersonEntity,
919
- WebsetArticleEntity,
920
- WebsetResearchPaperEntity,
921
- WebsetCustomEntity,
922
- ]
979
+ entity: Union[
980
+ WebsetCompanyEntity,
981
+ WebsetPersonEntity,
982
+ WebsetArticleEntity,
983
+ WebsetResearchPaperEntity,
984
+ WebsetCustomEntity,
923
985
  ]
924
986
  """
925
987
  The entity the search will return results for.
@@ -938,7 +1000,7 @@ class WebsetSearch(ExaBaseModel):
938
1000
  """
939
1001
  The progress of the search
940
1002
  """
941
- metadata: Optional[Dict[str, Any]] = None
1003
+ metadata: Optional[Dict[str, Any]] = {}
942
1004
  """
943
1005
  Set of key-value pairs you want to associate with this object.
944
1006
  """
@@ -964,7 +1026,7 @@ class WebsetSearchBehaviour(Enum):
964
1026
  """
965
1027
  The behaviour of the Search when it is added to a Webset.
966
1028
 
967
- - `override`: the search will reuse the existing Items found in the Webset and evaluate them against the new criteria. Any Items that don't match the new criteria will not be discarded.
1029
+ - `override`: the search will reuse the existing Items found in the Webset and evaluate them against the new criteria. Any Items that don't match the new criteria will be discarded.
968
1030
  """
969
1031
 
970
1032
  override = 'override'
@@ -1051,4 +1113,4 @@ class GetWebsetResponse(Webset):
1051
1113
  items: Optional[List[WebsetItem]] = None
1052
1114
  """
1053
1115
  When expand query parameter contains `items`, this will contain the items in the webset
1054
- """
1116
+ """