exa-py 1.13.0__py3-none-any.whl → 1.13.2__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 +47 -125
- exa_py/research/__init__.py +9 -0
- exa_py/research/client.py +232 -0
- exa_py/research/models.py +98 -0
- exa_py/websets/_generator/pydantic/BaseModel.jinja2 +42 -0
- exa_py/websets/client.py +2 -1
- exa_py/websets/core/base.py +6 -2
- exa_py/websets/streams/__init__.py +4 -0
- exa_py/websets/streams/client.py +96 -0
- exa_py/websets/streams/runs/__init__.py +3 -0
- exa_py/websets/streams/runs/client.py +38 -0
- exa_py/websets/types.py +302 -49
- {exa_py-1.13.0.dist-info → exa_py-1.13.2.dist-info}/METADATA +54 -16
- exa_py-1.13.2.dist-info/RECORD +28 -0
- {exa_py-1.13.0.dist-info → exa_py-1.13.2.dist-info}/WHEEL +1 -2
- exa_py-1.13.0.dist-info/RECORD +0 -21
- exa_py-1.13.0.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{% for decorator in decorators -%}
|
|
2
|
+
{{ decorator }}
|
|
3
|
+
{% endfor -%}
|
|
4
|
+
class {{ class_name }}({{ base_class }}):{% if comment is defined %} # {{ comment }}{% endif %}
|
|
5
|
+
{%- if description %}
|
|
6
|
+
"""
|
|
7
|
+
{{ description | indent(4) }}
|
|
8
|
+
"""
|
|
9
|
+
{%- endif %}
|
|
10
|
+
{%- if not fields and not description %}
|
|
11
|
+
pass
|
|
12
|
+
{%- endif %}
|
|
13
|
+
{%- if config %}
|
|
14
|
+
{%- filter indent(4) %}
|
|
15
|
+
{%- endfilter %}
|
|
16
|
+
{%- endif %}
|
|
17
|
+
{%- for field in fields -%}
|
|
18
|
+
{%- if field.name == "type" and field.field %}
|
|
19
|
+
type: Literal['{{ field.default }}']
|
|
20
|
+
{%- elif field.name == "object" and field.field %}
|
|
21
|
+
object: Literal['{{ field.default }}']
|
|
22
|
+
{%- elif not field.annotated and field.field %}
|
|
23
|
+
{{ field.name }}: {{ field.type_hint }} = {{ field.field }}
|
|
24
|
+
{%- else %}
|
|
25
|
+
{%- if field.annotated %}
|
|
26
|
+
{{ field.name }}: {{ field.annotated }}
|
|
27
|
+
{%- else %}
|
|
28
|
+
{{ field.name }}: {{ field.type_hint }}
|
|
29
|
+
{%- endif %}
|
|
30
|
+
{%- if not (field.required or (field.represented_default == 'None' and field.strip_default_none)) or field.data_type.is_optional
|
|
31
|
+
%} = {{ field.represented_default }}
|
|
32
|
+
{%- endif -%}
|
|
33
|
+
{%- endif %}
|
|
34
|
+
{%- if field.docstring %}
|
|
35
|
+
"""
|
|
36
|
+
{{ field.docstring | indent(4) }}
|
|
37
|
+
"""
|
|
38
|
+
{%- endif %}
|
|
39
|
+
{%- for method in methods -%}
|
|
40
|
+
{{ method }}
|
|
41
|
+
{%- endfor -%}
|
|
42
|
+
{%- endfor -%}
|
exa_py/websets/client.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
|
-
from datetime import datetime
|
|
5
4
|
from typing import List, Optional, Literal, Dict, Any, Union
|
|
6
5
|
|
|
7
6
|
from .types import (
|
|
@@ -17,6 +16,7 @@ from .items import WebsetItemsClient
|
|
|
17
16
|
from .searches import WebsetSearchesClient
|
|
18
17
|
from .enrichments import WebsetEnrichmentsClient
|
|
19
18
|
from .webhooks import WebsetWebhooksClient
|
|
19
|
+
from .streams import StreamsClient
|
|
20
20
|
|
|
21
21
|
class WebsetsClient(WebsetsBaseClient):
|
|
22
22
|
"""Client for managing Websets."""
|
|
@@ -27,6 +27,7 @@ class WebsetsClient(WebsetsBaseClient):
|
|
|
27
27
|
self.searches = WebsetSearchesClient(client)
|
|
28
28
|
self.enrichments = WebsetEnrichmentsClient(client)
|
|
29
29
|
self.webhooks = WebsetWebhooksClient(client)
|
|
30
|
+
self.streams = StreamsClient(client)
|
|
30
31
|
|
|
31
32
|
def create(self, params: Union[Dict[str, Any], CreateWebsetParameters]) -> Webset:
|
|
32
33
|
"""Create a new Webset.
|
exa_py/websets/core/base.py
CHANGED
|
@@ -29,7 +29,7 @@ class ExaBaseModel(BaseModel):
|
|
|
29
29
|
str_to_upper=False, # Don't convert strings to uppercase
|
|
30
30
|
from_attributes=True, # Allow initialization from attributes
|
|
31
31
|
validate_assignment=True, # Validate on assignment
|
|
32
|
-
extra='
|
|
32
|
+
extra='allow',
|
|
33
33
|
json_encoders={AnyUrl: str} # Convert AnyUrl to string when serializing to JSON
|
|
34
34
|
)
|
|
35
35
|
|
|
@@ -92,5 +92,9 @@ class WebsetsBaseClient:
|
|
|
92
92
|
# If data is a model instance, convert it to a dict
|
|
93
93
|
data = data.model_dump(by_alias=True, exclude_none=True)
|
|
94
94
|
|
|
95
|
+
# Ensure proper URL construction by removing leading slash from endpoint if present
|
|
96
|
+
if endpoint.startswith("/"):
|
|
97
|
+
endpoint = endpoint[1:]
|
|
98
|
+
|
|
95
99
|
return self._client.request("/websets/" + endpoint, data=data, method=method, params=params)
|
|
96
|
-
|
|
100
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Any, Union, Optional
|
|
4
|
+
|
|
5
|
+
from ..types import (
|
|
6
|
+
Stream,
|
|
7
|
+
CreateStreamParameters,
|
|
8
|
+
UpdateStream,
|
|
9
|
+
ListStreamsResponse,
|
|
10
|
+
)
|
|
11
|
+
from ..core.base import WebsetsBaseClient
|
|
12
|
+
from .runs import StreamRunsClient
|
|
13
|
+
|
|
14
|
+
class StreamsClient(WebsetsBaseClient):
|
|
15
|
+
"""Client for managing Streams."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, client):
|
|
18
|
+
super().__init__(client)
|
|
19
|
+
self.runs = StreamRunsClient(client)
|
|
20
|
+
|
|
21
|
+
def create(self, params: Union[Dict[str, Any], CreateStreamParameters]) -> Stream:
|
|
22
|
+
"""Create a new Stream to continuously keep your Websets updated with fresh data.
|
|
23
|
+
|
|
24
|
+
Streams automatically run on your defined schedule to ensure your Websets stay current without manual intervention:
|
|
25
|
+
- Find new content: Execute search operations to discover fresh items matching your criteria
|
|
26
|
+
- Update existing content: Run refresh operations to update items contents and enrichments
|
|
27
|
+
- Automated scheduling: Configure frequency, timezone, and execution times
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
params (CreateStreamParameters): The parameters for creating a stream.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Stream: The created stream.
|
|
34
|
+
"""
|
|
35
|
+
response = self.request("/v0/streams", data=params)
|
|
36
|
+
return Stream.model_validate(response)
|
|
37
|
+
|
|
38
|
+
def get(self, stream_id: str) -> Stream:
|
|
39
|
+
"""Get a specific stream.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
stream_id (str): The id of the Stream.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Stream: The retrieved stream.
|
|
46
|
+
"""
|
|
47
|
+
response = self.request(f"/v0/streams/{stream_id}", method="GET")
|
|
48
|
+
return Stream.model_validate(response)
|
|
49
|
+
|
|
50
|
+
def list(self, *, cursor: Optional[str] = None, limit: Optional[int] = None, webset_id: Optional[str] = None) -> ListStreamsResponse:
|
|
51
|
+
"""List all streams.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
cursor (str, optional): The cursor to paginate through the results.
|
|
55
|
+
limit (int, optional): The number of results to return (1-200, default 25).
|
|
56
|
+
webset_id (str, optional): The id of the Webset to list streams for.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
ListStreamsResponse: List of streams with pagination info.
|
|
60
|
+
"""
|
|
61
|
+
params = {
|
|
62
|
+
k: v
|
|
63
|
+
for k, v in {
|
|
64
|
+
"cursor": cursor,
|
|
65
|
+
"limit": limit,
|
|
66
|
+
"websetId": webset_id
|
|
67
|
+
}.items()
|
|
68
|
+
if v is not None
|
|
69
|
+
}
|
|
70
|
+
response = self.request("/v0/streams", params=params, method="GET")
|
|
71
|
+
return ListStreamsResponse.model_validate(response)
|
|
72
|
+
|
|
73
|
+
def update(self, stream_id: str, params: Union[Dict[str, Any], UpdateStream]) -> Stream:
|
|
74
|
+
"""Update a stream configuration.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
stream_id (str): The id of the Stream.
|
|
78
|
+
params (UpdateStream): The parameters for updating a stream.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Stream: The updated stream.
|
|
82
|
+
"""
|
|
83
|
+
response = self.request(f"/v0/streams/{stream_id}", data=params, method="PATCH")
|
|
84
|
+
return Stream.model_validate(response)
|
|
85
|
+
|
|
86
|
+
def delete(self, stream_id: str) -> Stream:
|
|
87
|
+
"""Delete a stream.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
stream_id (str): The id of the Stream.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Stream: The deleted stream.
|
|
94
|
+
"""
|
|
95
|
+
response = self.request(f"/v0/streams/{stream_id}", method="DELETE")
|
|
96
|
+
return Stream.model_validate(response)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ...types import (
|
|
4
|
+
StreamRun,
|
|
5
|
+
ListStreamRunsResponse,
|
|
6
|
+
)
|
|
7
|
+
from ...core.base import WebsetsBaseClient
|
|
8
|
+
|
|
9
|
+
class StreamRunsClient(WebsetsBaseClient):
|
|
10
|
+
"""Client for managing Stream Runs."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, client):
|
|
13
|
+
super().__init__(client)
|
|
14
|
+
|
|
15
|
+
def list(self, stream_id: str) -> ListStreamRunsResponse:
|
|
16
|
+
"""List all runs for the Stream.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
stream_id (str): The id of the Stream to list runs for.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
ListStreamRunsResponse: List of stream runs.
|
|
23
|
+
"""
|
|
24
|
+
response = self.request(f"/v0/streams/{stream_id}/runs", method="GET")
|
|
25
|
+
return ListStreamRunsResponse.model_validate(response)
|
|
26
|
+
|
|
27
|
+
def get(self, stream_id: str, run_id: str) -> StreamRun:
|
|
28
|
+
"""Get a specific stream run.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
stream_id (str): The id of the Stream to get the run for.
|
|
32
|
+
run_id (str): The id of the stream run.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
StreamRun: The stream run details.
|
|
36
|
+
"""
|
|
37
|
+
response = self.request(f"/v0/streams/{stream_id}/runs/{run_id}", method="GET")
|
|
38
|
+
return StreamRun.model_validate(response)
|