seltz 0.1.1__tar.gz → 0.1.3__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.
- seltz-0.1.3/PKG-INFO +236 -0
- seltz-0.1.3/README.md +211 -0
- {seltz-0.1.1 → seltz-0.1.3}/pyproject.toml +5 -5
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz/__init__.py +7 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz/client.py +2 -1
- seltz-0.1.3/src/seltz/seltz.py +79 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz/services/search_service.py +29 -8
- seltz-0.1.3/src/seltz/types.py +285 -0
- seltz-0.1.3/src/seltz.egg-info/PKG-INFO +236 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz.egg-info/SOURCES.txt +1 -0
- seltz-0.1.3/src/seltz.egg-info/requires.txt +2 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz_public_api/proto/v1/seltz_pb2.py +12 -12
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz_public_api/proto/v1/seltz_pb2.pyi +9 -12
- seltz-0.1.1/PKG-INFO +0 -124
- seltz-0.1.1/README.md +0 -99
- seltz-0.1.1/src/seltz/seltz.py +0 -48
- seltz-0.1.1/src/seltz.egg-info/PKG-INFO +0 -124
- seltz-0.1.1/src/seltz.egg-info/requires.txt +0 -2
- {seltz-0.1.1 → seltz-0.1.3}/setup.cfg +0 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz/exceptions.py +0 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz/services/__init__.py +0 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz.egg-info/dependency_links.txt +0 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz.egg-info/top_level.txt +0 -0
- {seltz-0.1.1 → seltz-0.1.3}/src/seltz_public_api/proto/v1/seltz_pb2_grpc.py +0 -0
seltz-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seltz
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Seltz Python SDK for AI-powered search
|
|
5
|
+
Author-email: Seltz <support@seltz.ai>
|
|
6
|
+
Project-URL: Homepage, https://seltz.ai
|
|
7
|
+
Project-URL: Documentation, https://docs.seltz.ai
|
|
8
|
+
Project-URL: Repository, https://github.com/seltz-ai/seltz-python-sdk
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/seltz-ai/seltz-python-sdk/issues
|
|
10
|
+
Keywords: search,ai,sdk,api
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: grpcio>=1.76.0
|
|
24
|
+
Requires-Dist: protobuf<6.0
|
|
25
|
+
|
|
26
|
+
# Seltz Python SDK
|
|
27
|
+
|
|
28
|
+
The official Python SDK for the Seltz AI-powered search API.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install seltz
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from seltz import Seltz
|
|
40
|
+
|
|
41
|
+
# Initialize with API key
|
|
42
|
+
client = Seltz(api_key="your-api-key")
|
|
43
|
+
|
|
44
|
+
# Perform a search
|
|
45
|
+
response = client.search("your search query")
|
|
46
|
+
|
|
47
|
+
# Access results
|
|
48
|
+
for document in response.documents:
|
|
49
|
+
print(f"URL: {document.url}")
|
|
50
|
+
print(f"Content: {document.content}")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## API Key
|
|
54
|
+
|
|
55
|
+
Set your API key using one of these methods:
|
|
56
|
+
|
|
57
|
+
1. **Environment variable** (recommended):
|
|
58
|
+
```bash
|
|
59
|
+
export SELTZ_API_KEY="your-api-key"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. **Direct parameter**:
|
|
63
|
+
```python
|
|
64
|
+
client = Seltz(api_key="your-api-key")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `Seltz(api_key=None, endpoint="grpc.seltz.ai", insecure=False)`
|
|
70
|
+
|
|
71
|
+
Creates a new Seltz client instance.
|
|
72
|
+
|
|
73
|
+
**Parameters:**
|
|
74
|
+
- `api_key` (str, optional): API key for authentication. Defaults to `SELTZ_API_KEY` environment variable.
|
|
75
|
+
- `endpoint` (str): API endpoint. Defaults to "grpc.seltz.ai".
|
|
76
|
+
- `insecure` (bool): Use insecure connection. Defaults to False.
|
|
77
|
+
|
|
78
|
+
**Returns:** `Seltz` instance
|
|
79
|
+
|
|
80
|
+
### `client.search(query, *, includes=None, context=None, profile=None)`
|
|
81
|
+
|
|
82
|
+
Performs a search query.
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
- `query` (str): The search query text. Keep concise for best performance.
|
|
86
|
+
- `includes` (Includes | int, optional): What to include in results.
|
|
87
|
+
- `context` (str, optional): Additional context for the query. Include as much relevant information as feasible to improve search quality.
|
|
88
|
+
- `profile` (str, optional): Search profile to use (contact support for available profiles).
|
|
89
|
+
|
|
90
|
+
**Returns:** `SearchResult` with documents and helper methods.
|
|
91
|
+
|
|
92
|
+
**Examples:**
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
response = client.search("Python asyncio tutorial")
|
|
96
|
+
|
|
97
|
+
# With Includes configuration
|
|
98
|
+
from seltz import Includes
|
|
99
|
+
response = client.search(
|
|
100
|
+
"Python tutorial",
|
|
101
|
+
includes=Includes(max_documents=10)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Access results
|
|
105
|
+
for doc in response:
|
|
106
|
+
print(f"URL: {doc.url}")
|
|
107
|
+
print(f"Content: {doc.content}")
|
|
108
|
+
|
|
109
|
+
# Or use helper methods
|
|
110
|
+
first_doc = response.first()
|
|
111
|
+
all_urls = response.get_urls()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### `Includess`
|
|
115
|
+
|
|
116
|
+
Configuration for what to include in search results.
|
|
117
|
+
|
|
118
|
+
**Parameters:**
|
|
119
|
+
- `max_documents` (int, optional): Maximum number of documents to return.
|
|
120
|
+
|
|
121
|
+
**Constructor Pattern (simple cases):**
|
|
122
|
+
```python
|
|
123
|
+
from seltz import Includes
|
|
124
|
+
|
|
125
|
+
# Simple constructor
|
|
126
|
+
includes = Includes(max_documents=5)
|
|
127
|
+
response = client.search("query", includes=includes)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Fluent Builder Pattern (complex cases):**
|
|
131
|
+
```python
|
|
132
|
+
from seltz import Includes
|
|
133
|
+
|
|
134
|
+
# Single field
|
|
135
|
+
includes = Includes().max_documents(10)
|
|
136
|
+
|
|
137
|
+
# Mixed approach
|
|
138
|
+
includes = Includes(max_documents=5).max_documents(10)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### `SearchResult`
|
|
142
|
+
|
|
143
|
+
Search result wrapper with helper methods.
|
|
144
|
+
|
|
145
|
+
**Properties:**
|
|
146
|
+
- `documents`: List of Document objects
|
|
147
|
+
|
|
148
|
+
**Methods:**
|
|
149
|
+
- `__len__()`: Get number of documents (`len(result)`)
|
|
150
|
+
- `__iter__()`: Iterate over documents (`for doc in result:`)
|
|
151
|
+
- `__getitem__(index)`: Get document by index (`result[0]`, `result[-1]`)
|
|
152
|
+
- `first()`: Get first document (or None if empty)
|
|
153
|
+
- `get_urls()`: Get list of all URLs
|
|
154
|
+
- `get_contents()`: Get list of all contents
|
|
155
|
+
- `to_dict()`: Convert to dictionary for JSON serialization
|
|
156
|
+
|
|
157
|
+
**Example:**
|
|
158
|
+
```python
|
|
159
|
+
result = client.search("Python tutorial")
|
|
160
|
+
|
|
161
|
+
print(f"Found {len(result)} documents")
|
|
162
|
+
|
|
163
|
+
for doc in result:
|
|
164
|
+
print(doc.url)
|
|
165
|
+
|
|
166
|
+
first = result.first()
|
|
167
|
+
if first:
|
|
168
|
+
print(f"Top result: {first.url}")
|
|
169
|
+
|
|
170
|
+
urls = result.get_urls()
|
|
171
|
+
|
|
172
|
+
import json
|
|
173
|
+
json_data = json.dumps(result.to_dict())
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### `Document`
|
|
177
|
+
|
|
178
|
+
Individual search result document.
|
|
179
|
+
|
|
180
|
+
**Properties:**
|
|
181
|
+
- `url`: Document URL (optional)
|
|
182
|
+
- `content`: Document content (optional)
|
|
183
|
+
|
|
184
|
+
**Methods:**
|
|
185
|
+
- `has_url()`: Check if URL exists
|
|
186
|
+
- `has_content()`: Check if content exists
|
|
187
|
+
- `to_dict()`: Convert to dictionary
|
|
188
|
+
|
|
189
|
+
**Example:**
|
|
190
|
+
```python
|
|
191
|
+
doc = result[0]
|
|
192
|
+
|
|
193
|
+
if doc.has_url():
|
|
194
|
+
print(f"URL: {doc.url}")
|
|
195
|
+
|
|
196
|
+
if doc.has_content():
|
|
197
|
+
print(f"Content: {doc.content[:100]}")
|
|
198
|
+
|
|
199
|
+
doc_dict = doc.to_dict()
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Error Handling
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from seltz import (
|
|
206
|
+
Seltz,
|
|
207
|
+
SeltzConfigurationError,
|
|
208
|
+
SeltzAuthenticationError,
|
|
209
|
+
SeltzConnectionError,
|
|
210
|
+
SeltzAPIError,
|
|
211
|
+
SeltzTimeoutError,
|
|
212
|
+
SeltzRateLimitError,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
client = Seltz(api_key="your-api-key")
|
|
217
|
+
response = client.search("query")
|
|
218
|
+
except SeltzConfigurationError as e:
|
|
219
|
+
print(f"Configuration error: {e}")
|
|
220
|
+
except SeltzAuthenticationError as e:
|
|
221
|
+
print(f"Authentication error: {e}")
|
|
222
|
+
except SeltzConnectionError as e:
|
|
223
|
+
print(f"Connection error: {e}")
|
|
224
|
+
except SeltzTimeoutError as e:
|
|
225
|
+
print(f"Timeout error: {e}")
|
|
226
|
+
except SeltzRateLimitError as e:
|
|
227
|
+
print(f"Rate limit error: {e}")
|
|
228
|
+
except SeltzAPIError as e:
|
|
229
|
+
print(f"API error: {e}")
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Requirements
|
|
233
|
+
|
|
234
|
+
- Python 3.8+
|
|
235
|
+
- grpcio >= 1.76.0
|
|
236
|
+
- protobuf < 6.0
|
seltz-0.1.3/README.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Seltz Python SDK
|
|
2
|
+
|
|
3
|
+
The official Python SDK for the Seltz AI-powered search API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install seltz
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from seltz import Seltz
|
|
15
|
+
|
|
16
|
+
# Initialize with API key
|
|
17
|
+
client = Seltz(api_key="your-api-key")
|
|
18
|
+
|
|
19
|
+
# Perform a search
|
|
20
|
+
response = client.search("your search query")
|
|
21
|
+
|
|
22
|
+
# Access results
|
|
23
|
+
for document in response.documents:
|
|
24
|
+
print(f"URL: {document.url}")
|
|
25
|
+
print(f"Content: {document.content}")
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API Key
|
|
29
|
+
|
|
30
|
+
Set your API key using one of these methods:
|
|
31
|
+
|
|
32
|
+
1. **Environment variable** (recommended):
|
|
33
|
+
```bash
|
|
34
|
+
export SELTZ_API_KEY="your-api-key"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. **Direct parameter**:
|
|
38
|
+
```python
|
|
39
|
+
client = Seltz(api_key="your-api-key")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### `Seltz(api_key=None, endpoint="grpc.seltz.ai", insecure=False)`
|
|
45
|
+
|
|
46
|
+
Creates a new Seltz client instance.
|
|
47
|
+
|
|
48
|
+
**Parameters:**
|
|
49
|
+
- `api_key` (str, optional): API key for authentication. Defaults to `SELTZ_API_KEY` environment variable.
|
|
50
|
+
- `endpoint` (str): API endpoint. Defaults to "grpc.seltz.ai".
|
|
51
|
+
- `insecure` (bool): Use insecure connection. Defaults to False.
|
|
52
|
+
|
|
53
|
+
**Returns:** `Seltz` instance
|
|
54
|
+
|
|
55
|
+
### `client.search(query, *, includes=None, context=None, profile=None)`
|
|
56
|
+
|
|
57
|
+
Performs a search query.
|
|
58
|
+
|
|
59
|
+
**Parameters:**
|
|
60
|
+
- `query` (str): The search query text. Keep concise for best performance.
|
|
61
|
+
- `includes` (Includes | int, optional): What to include in results.
|
|
62
|
+
- `context` (str, optional): Additional context for the query. Include as much relevant information as feasible to improve search quality.
|
|
63
|
+
- `profile` (str, optional): Search profile to use (contact support for available profiles).
|
|
64
|
+
|
|
65
|
+
**Returns:** `SearchResult` with documents and helper methods.
|
|
66
|
+
|
|
67
|
+
**Examples:**
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
response = client.search("Python asyncio tutorial")
|
|
71
|
+
|
|
72
|
+
# With Includes configuration
|
|
73
|
+
from seltz import Includes
|
|
74
|
+
response = client.search(
|
|
75
|
+
"Python tutorial",
|
|
76
|
+
includes=Includes(max_documents=10)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Access results
|
|
80
|
+
for doc in response:
|
|
81
|
+
print(f"URL: {doc.url}")
|
|
82
|
+
print(f"Content: {doc.content}")
|
|
83
|
+
|
|
84
|
+
# Or use helper methods
|
|
85
|
+
first_doc = response.first()
|
|
86
|
+
all_urls = response.get_urls()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `Includess`
|
|
90
|
+
|
|
91
|
+
Configuration for what to include in search results.
|
|
92
|
+
|
|
93
|
+
**Parameters:**
|
|
94
|
+
- `max_documents` (int, optional): Maximum number of documents to return.
|
|
95
|
+
|
|
96
|
+
**Constructor Pattern (simple cases):**
|
|
97
|
+
```python
|
|
98
|
+
from seltz import Includes
|
|
99
|
+
|
|
100
|
+
# Simple constructor
|
|
101
|
+
includes = Includes(max_documents=5)
|
|
102
|
+
response = client.search("query", includes=includes)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Fluent Builder Pattern (complex cases):**
|
|
106
|
+
```python
|
|
107
|
+
from seltz import Includes
|
|
108
|
+
|
|
109
|
+
# Single field
|
|
110
|
+
includes = Includes().max_documents(10)
|
|
111
|
+
|
|
112
|
+
# Mixed approach
|
|
113
|
+
includes = Includes(max_documents=5).max_documents(10)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `SearchResult`
|
|
117
|
+
|
|
118
|
+
Search result wrapper with helper methods.
|
|
119
|
+
|
|
120
|
+
**Properties:**
|
|
121
|
+
- `documents`: List of Document objects
|
|
122
|
+
|
|
123
|
+
**Methods:**
|
|
124
|
+
- `__len__()`: Get number of documents (`len(result)`)
|
|
125
|
+
- `__iter__()`: Iterate over documents (`for doc in result:`)
|
|
126
|
+
- `__getitem__(index)`: Get document by index (`result[0]`, `result[-1]`)
|
|
127
|
+
- `first()`: Get first document (or None if empty)
|
|
128
|
+
- `get_urls()`: Get list of all URLs
|
|
129
|
+
- `get_contents()`: Get list of all contents
|
|
130
|
+
- `to_dict()`: Convert to dictionary for JSON serialization
|
|
131
|
+
|
|
132
|
+
**Example:**
|
|
133
|
+
```python
|
|
134
|
+
result = client.search("Python tutorial")
|
|
135
|
+
|
|
136
|
+
print(f"Found {len(result)} documents")
|
|
137
|
+
|
|
138
|
+
for doc in result:
|
|
139
|
+
print(doc.url)
|
|
140
|
+
|
|
141
|
+
first = result.first()
|
|
142
|
+
if first:
|
|
143
|
+
print(f"Top result: {first.url}")
|
|
144
|
+
|
|
145
|
+
urls = result.get_urls()
|
|
146
|
+
|
|
147
|
+
import json
|
|
148
|
+
json_data = json.dumps(result.to_dict())
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `Document`
|
|
152
|
+
|
|
153
|
+
Individual search result document.
|
|
154
|
+
|
|
155
|
+
**Properties:**
|
|
156
|
+
- `url`: Document URL (optional)
|
|
157
|
+
- `content`: Document content (optional)
|
|
158
|
+
|
|
159
|
+
**Methods:**
|
|
160
|
+
- `has_url()`: Check if URL exists
|
|
161
|
+
- `has_content()`: Check if content exists
|
|
162
|
+
- `to_dict()`: Convert to dictionary
|
|
163
|
+
|
|
164
|
+
**Example:**
|
|
165
|
+
```python
|
|
166
|
+
doc = result[0]
|
|
167
|
+
|
|
168
|
+
if doc.has_url():
|
|
169
|
+
print(f"URL: {doc.url}")
|
|
170
|
+
|
|
171
|
+
if doc.has_content():
|
|
172
|
+
print(f"Content: {doc.content[:100]}")
|
|
173
|
+
|
|
174
|
+
doc_dict = doc.to_dict()
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Error Handling
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from seltz import (
|
|
181
|
+
Seltz,
|
|
182
|
+
SeltzConfigurationError,
|
|
183
|
+
SeltzAuthenticationError,
|
|
184
|
+
SeltzConnectionError,
|
|
185
|
+
SeltzAPIError,
|
|
186
|
+
SeltzTimeoutError,
|
|
187
|
+
SeltzRateLimitError,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
client = Seltz(api_key="your-api-key")
|
|
192
|
+
response = client.search("query")
|
|
193
|
+
except SeltzConfigurationError as e:
|
|
194
|
+
print(f"Configuration error: {e}")
|
|
195
|
+
except SeltzAuthenticationError as e:
|
|
196
|
+
print(f"Authentication error: {e}")
|
|
197
|
+
except SeltzConnectionError as e:
|
|
198
|
+
print(f"Connection error: {e}")
|
|
199
|
+
except SeltzTimeoutError as e:
|
|
200
|
+
print(f"Timeout error: {e}")
|
|
201
|
+
except SeltzRateLimitError as e:
|
|
202
|
+
print(f"Rate limit error: {e}")
|
|
203
|
+
except SeltzAPIError as e:
|
|
204
|
+
print(f"API error: {e}")
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Requirements
|
|
208
|
+
|
|
209
|
+
- Python 3.8+
|
|
210
|
+
- grpcio >= 1.76.0
|
|
211
|
+
- protobuf < 6.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "seltz"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "Seltz Python SDK for AI-powered search"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -26,14 +26,14 @@ classifiers = [
|
|
|
26
26
|
]
|
|
27
27
|
dependencies = [
|
|
28
28
|
"grpcio>=1.76.0",
|
|
29
|
-
"protobuf
|
|
29
|
+
"protobuf<6.0",
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.urls]
|
|
33
33
|
Homepage = "https://seltz.ai"
|
|
34
34
|
Documentation = "https://docs.seltz.ai"
|
|
35
|
-
Repository = "https://github.com/seltz-ai/seltz-
|
|
36
|
-
"Bug Tracker" = "https://github.com/seltz-ai/seltz-
|
|
35
|
+
Repository = "https://github.com/seltz-ai/seltz-python-sdk"
|
|
36
|
+
"Bug Tracker" = "https://github.com/seltz-ai/seltz-python-sdk/issues"
|
|
37
37
|
|
|
38
38
|
[tool.setuptools.packages.find]
|
|
39
39
|
where = ["src"]
|
|
@@ -57,5 +57,5 @@ split-on-trailing-comma = true
|
|
|
57
57
|
|
|
58
58
|
[tool.ruff]
|
|
59
59
|
exclude = [
|
|
60
|
-
"src/
|
|
60
|
+
"src/seltz_public_api/"
|
|
61
61
|
]
|
|
@@ -10,9 +10,16 @@ from .exceptions import (
|
|
|
10
10
|
SeltzTimeoutError,
|
|
11
11
|
)
|
|
12
12
|
from .seltz import Seltz
|
|
13
|
+
from .types import Document, Includes, SearchResult
|
|
13
14
|
|
|
14
15
|
__all__ = [
|
|
16
|
+
# Main client
|
|
15
17
|
"Seltz",
|
|
18
|
+
# Types
|
|
19
|
+
"Includes",
|
|
20
|
+
"SearchResult",
|
|
21
|
+
"Document",
|
|
22
|
+
# Exceptions
|
|
16
23
|
"SeltzError",
|
|
17
24
|
"SeltzConfigurationError",
|
|
18
25
|
"SeltzAuthenticationError",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import grpc
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class SeltzClient:
|
|
5
6
|
"""Low-level gRPC client for Seltz API."""
|
|
6
7
|
|
|
7
8
|
def __init__(
|
|
8
|
-
self, endpoint: str, api_key: str
|
|
9
|
+
self, endpoint: str, api_key: Optional[str] = None, insecure: bool = False
|
|
9
10
|
):
|
|
10
11
|
"""Initialize the Seltz gRPC client.
|
|
11
12
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from .client import SeltzClient
|
|
5
|
+
from .exceptions import SeltzConfigurationError
|
|
6
|
+
from .services.search_service import SearchService
|
|
7
|
+
from .types import Includes, SearchResult
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Seltz:
|
|
11
|
+
"""Main Seltz SDK client for interacting with the Seltz API."""
|
|
12
|
+
|
|
13
|
+
_ENDPOINT: str = "grpc.seltz.ai"
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
api_key: Optional[str] = os.environ.get("SELTZ_API_KEY"),
|
|
18
|
+
endpoint: str = _ENDPOINT,
|
|
19
|
+
insecure: bool = False,
|
|
20
|
+
):
|
|
21
|
+
"""Initialize the Seltz client.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
api_key: API key for authentication. If None, will try to read from SELTZ_API_KEY environment variable
|
|
25
|
+
endpoint: The API endpoint to connect to (default: grpc.seltz.ai)
|
|
26
|
+
insecure: Whether to use insecure connection (default: False)
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Seltz: A new Seltz client instance
|
|
30
|
+
|
|
31
|
+
Raises:
|
|
32
|
+
SeltzConfigurationError: If no API key is provided
|
|
33
|
+
"""
|
|
34
|
+
if api_key is None:
|
|
35
|
+
raise SeltzConfigurationError("No API key provided")
|
|
36
|
+
self._client = SeltzClient(
|
|
37
|
+
endpoint=endpoint, api_key=api_key, insecure=insecure
|
|
38
|
+
)
|
|
39
|
+
self._search = SearchService(self._client.channel, self._client.api_key)
|
|
40
|
+
|
|
41
|
+
def search(
|
|
42
|
+
self,
|
|
43
|
+
query: str,
|
|
44
|
+
*,
|
|
45
|
+
includes: Optional[Includes] = None,
|
|
46
|
+
context: Optional[str] = None,
|
|
47
|
+
profile: Optional[str] = None,
|
|
48
|
+
) -> SearchResult:
|
|
49
|
+
"""Perform a search query.
|
|
50
|
+
|
|
51
|
+
This method searches using the Seltz AI-powered search engine. You can
|
|
52
|
+
customize the search behavior using optional parameters.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
query: The search query string. Keep this concise for best performance.
|
|
56
|
+
includes: Configuration for what to include in results. If not specified
|
|
57
|
+
server defaults are used.
|
|
58
|
+
context: Additional context for the query. Include as much relevant
|
|
59
|
+
information as feasible to improve search quality. For example,
|
|
60
|
+
"user is looking for Python documentation for beginners".
|
|
61
|
+
profile: Search profile to use. Different profiles may use different
|
|
62
|
+
ranking algorithms or have different data source preferences.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
SearchResult: Search results containing documents and metadata.
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
SeltzAuthenticationError: If API key is invalid
|
|
69
|
+
SeltzConnectionError: If connection to API fails
|
|
70
|
+
SeltzTimeoutError: If request times out
|
|
71
|
+
SeltzRateLimitError: If rate limit is exceeded
|
|
72
|
+
SeltzAPIError: For other API errors
|
|
73
|
+
"""
|
|
74
|
+
return self._search.search(
|
|
75
|
+
query=query,
|
|
76
|
+
includes=includes,
|
|
77
|
+
context=context,
|
|
78
|
+
profile=profile,
|
|
79
|
+
)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
import grpc
|
|
2
4
|
|
|
3
5
|
from ..exceptions import (
|
|
@@ -7,7 +9,8 @@ from ..exceptions import (
|
|
|
7
9
|
SeltzRateLimitError,
|
|
8
10
|
SeltzTimeoutError,
|
|
9
11
|
)
|
|
10
|
-
from
|
|
12
|
+
from ..types import Includes, SearchResult
|
|
13
|
+
from . import SearchRequest, SeltzServiceStub
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class SearchService:
|
|
@@ -23,28 +26,46 @@ class SearchService:
|
|
|
23
26
|
self._stub = SeltzServiceStub(channel)
|
|
24
27
|
self._api_key = api_key
|
|
25
28
|
|
|
26
|
-
def search(
|
|
29
|
+
def search(
|
|
30
|
+
self,
|
|
31
|
+
query: str,
|
|
32
|
+
*,
|
|
33
|
+
includes: Optional[Includes] = None,
|
|
34
|
+
context: Optional[str] = None,
|
|
35
|
+
profile: Optional[str] = None,
|
|
36
|
+
) -> SearchResult:
|
|
27
37
|
"""Perform a search query.
|
|
28
38
|
|
|
29
39
|
Args:
|
|
30
40
|
query: The search query string
|
|
31
|
-
|
|
41
|
+
includes: Either an Includes object
|
|
42
|
+
context: Additional context for the query
|
|
43
|
+
profile: Search profile to use
|
|
32
44
|
|
|
33
45
|
Returns:
|
|
34
|
-
|
|
46
|
+
SearchResult: Wrapped search response with helper methods
|
|
35
47
|
|
|
36
48
|
Raises:
|
|
37
|
-
|
|
49
|
+
SeltzAuthenticationError: If authentication fails
|
|
50
|
+
SeltzConnectionError: If connection fails
|
|
51
|
+
SeltzTimeoutError: If request times out
|
|
52
|
+
SeltzRateLimitError: If rate limit exceeded
|
|
53
|
+
SeltzAPIError: For other API errors
|
|
38
54
|
"""
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
req = SearchRequest(
|
|
56
|
+
query=query,
|
|
57
|
+
includes=includes._to_protobuf() if includes is not None else None,
|
|
58
|
+
context=context,
|
|
59
|
+
profile=profile,
|
|
60
|
+
api_key=self._api_key,
|
|
61
|
+
)
|
|
41
62
|
|
|
42
63
|
metadata = []
|
|
43
64
|
if self._api_key:
|
|
44
65
|
metadata.append(("authorization", f"Bearer {self._api_key}"))
|
|
45
66
|
|
|
46
67
|
try:
|
|
47
|
-
return self._stub.Search(req, metadata=metadata, timeout=30)
|
|
68
|
+
return SearchResult(self._stub.Search(req, metadata=metadata, timeout=30))
|
|
48
69
|
except grpc.RpcError as e:
|
|
49
70
|
if e.code() == grpc.StatusCode.UNAUTHENTICATED:
|
|
50
71
|
raise SeltzAuthenticationError(
|