serpex 2.2.0__tar.gz → 2.3.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.
- {serpex-2.2.0/src/serpex.egg-info → serpex-2.3.0}/PKG-INFO +31 -6
- {serpex-2.2.0 → serpex-2.3.0}/README.md +30 -5
- {serpex-2.2.0 → serpex-2.3.0}/pyproject.toml +1 -1
- {serpex-2.2.0 → serpex-2.3.0}/setup.py +6 -6
- {serpex-2.2.0 → serpex-2.3.0/src/serpex.egg-info}/PKG-INFO +31 -6
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex_sdk/client.py +50 -30
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex_sdk/types.py +15 -6
- {serpex-2.2.0 → serpex-2.3.0}/LICENSE +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/setup.cfg +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex.egg-info/SOURCES.txt +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex.egg-info/dependency_links.txt +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex.egg-info/requires.txt +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex.egg-info/top_level.txt +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex_sdk/__init__.py +0 -0
- {serpex-2.2.0 → serpex-2.3.0}/src/serpex_sdk/exceptions.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: serpex
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Official Python SDK for Serpex Search API - Fetch search results in JSON format
|
|
5
|
-
Home-page: https://github.com/divyeshradadiya/
|
|
5
|
+
Home-page: https://github.com/divyeshradadiya/serpex-sdk-python
|
|
6
6
|
Author: Serpex Team
|
|
7
7
|
Author-email: Serpex Team <support@serpex.dev>
|
|
8
8
|
License: MIT
|
|
@@ -162,16 +162,34 @@ class SearchParams:
|
|
|
162
162
|
# Optional: Engine selection (defaults to 'auto')
|
|
163
163
|
engine: Optional[str] = 'auto'
|
|
164
164
|
|
|
165
|
-
# Optional: Search category (
|
|
166
|
-
category: Optional[str] = 'web'
|
|
165
|
+
# Optional: Search category ('web' for general search, 'news' for news articles - always returns latest news)
|
|
166
|
+
category: Optional[str] = 'web' # Supports: 'web', 'news'
|
|
167
167
|
|
|
168
|
-
# Optional: Time range filter
|
|
168
|
+
# Optional: Time range filter (only applicable for 'web' category, ignored for 'news')
|
|
169
169
|
time_range: Optional[str] = 'all'
|
|
170
170
|
|
|
171
171
|
# Optional: Response format
|
|
172
172
|
format: Optional[str] = 'json'
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
### News Search Example
|
|
176
|
+
|
|
177
|
+
News search always returns the latest news articles. The `time_range` parameter is ignored for news searches.
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Search for latest news articles
|
|
181
|
+
news_results = client.search({
|
|
182
|
+
'q': 'artificial intelligence',
|
|
183
|
+
'engine': 'google',
|
|
184
|
+
'category': 'news' # Always returns latest news
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
print(news_results.results[0].title)
|
|
188
|
+
print(news_results.results[0].published_date)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
````
|
|
192
|
+
|
|
175
193
|
## Supported Engines
|
|
176
194
|
|
|
177
195
|
- **auto**: Automatically routes to the best available search engine
|
|
@@ -196,7 +214,7 @@ class SearchResponse:
|
|
|
196
214
|
corrections: List[str]
|
|
197
215
|
infoboxes: List[Any]
|
|
198
216
|
suggestions: List[str]
|
|
199
|
-
|
|
217
|
+
````
|
|
200
218
|
|
|
201
219
|
## Error Handling
|
|
202
220
|
|
|
@@ -216,6 +234,7 @@ except SerpApiException as e:
|
|
|
216
234
|
## Examples
|
|
217
235
|
|
|
218
236
|
### Basic Search
|
|
237
|
+
|
|
219
238
|
```python
|
|
220
239
|
results = client.search({
|
|
221
240
|
'q': 'coffee shops near me'
|
|
@@ -223,6 +242,7 @@ results = client.search({
|
|
|
223
242
|
```
|
|
224
243
|
|
|
225
244
|
### Advanced Search with Filters
|
|
245
|
+
|
|
226
246
|
```python
|
|
227
247
|
results = client.search({
|
|
228
248
|
'q': 'latest AI news',
|
|
@@ -233,6 +253,7 @@ results = client.search({
|
|
|
233
253
|
```
|
|
234
254
|
|
|
235
255
|
### Using SearchParams Object
|
|
256
|
+
|
|
236
257
|
```python
|
|
237
258
|
from serpex import SearchParams
|
|
238
259
|
|
|
@@ -247,6 +268,7 @@ results = client.search(params)
|
|
|
247
268
|
### Extract Web Content to LLM-Ready Data
|
|
248
269
|
|
|
249
270
|
#### Extract from a Single URL
|
|
271
|
+
|
|
250
272
|
```python
|
|
251
273
|
# Extract content from one website
|
|
252
274
|
result = client.extract({
|
|
@@ -259,6 +281,7 @@ if result.results[0].success:
|
|
|
259
281
|
```
|
|
260
282
|
|
|
261
283
|
#### Extract from Multiple URLs (up to 10 at once)
|
|
284
|
+
|
|
262
285
|
```python
|
|
263
286
|
# Extract content from multiple websites (up to 10 URLs)
|
|
264
287
|
extract_results = client.extract({
|
|
@@ -281,6 +304,7 @@ for result in extract_results.results:
|
|
|
281
304
|
```
|
|
282
305
|
|
|
283
306
|
#### Sample Response
|
|
307
|
+
|
|
284
308
|
```python
|
|
285
309
|
# Example response structure
|
|
286
310
|
{
|
|
@@ -306,6 +330,7 @@ for result in extract_results.results:
|
|
|
306
330
|
```
|
|
307
331
|
|
|
308
332
|
### Using ExtractParams Object
|
|
333
|
+
|
|
309
334
|
```python
|
|
310
335
|
from serpex import ExtractParams
|
|
311
336
|
|
|
@@ -127,16 +127,34 @@ class SearchParams:
|
|
|
127
127
|
# Optional: Engine selection (defaults to 'auto')
|
|
128
128
|
engine: Optional[str] = 'auto'
|
|
129
129
|
|
|
130
|
-
# Optional: Search category (
|
|
131
|
-
category: Optional[str] = 'web'
|
|
130
|
+
# Optional: Search category ('web' for general search, 'news' for news articles - always returns latest news)
|
|
131
|
+
category: Optional[str] = 'web' # Supports: 'web', 'news'
|
|
132
132
|
|
|
133
|
-
# Optional: Time range filter
|
|
133
|
+
# Optional: Time range filter (only applicable for 'web' category, ignored for 'news')
|
|
134
134
|
time_range: Optional[str] = 'all'
|
|
135
135
|
|
|
136
136
|
# Optional: Response format
|
|
137
137
|
format: Optional[str] = 'json'
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
+
### News Search Example
|
|
141
|
+
|
|
142
|
+
News search always returns the latest news articles. The `time_range` parameter is ignored for news searches.
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Search for latest news articles
|
|
146
|
+
news_results = client.search({
|
|
147
|
+
'q': 'artificial intelligence',
|
|
148
|
+
'engine': 'google',
|
|
149
|
+
'category': 'news' # Always returns latest news
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
print(news_results.results[0].title)
|
|
153
|
+
print(news_results.results[0].published_date)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
````
|
|
157
|
+
|
|
140
158
|
## Supported Engines
|
|
141
159
|
|
|
142
160
|
- **auto**: Automatically routes to the best available search engine
|
|
@@ -161,7 +179,7 @@ class SearchResponse:
|
|
|
161
179
|
corrections: List[str]
|
|
162
180
|
infoboxes: List[Any]
|
|
163
181
|
suggestions: List[str]
|
|
164
|
-
|
|
182
|
+
````
|
|
165
183
|
|
|
166
184
|
## Error Handling
|
|
167
185
|
|
|
@@ -181,6 +199,7 @@ except SerpApiException as e:
|
|
|
181
199
|
## Examples
|
|
182
200
|
|
|
183
201
|
### Basic Search
|
|
202
|
+
|
|
184
203
|
```python
|
|
185
204
|
results = client.search({
|
|
186
205
|
'q': 'coffee shops near me'
|
|
@@ -188,6 +207,7 @@ results = client.search({
|
|
|
188
207
|
```
|
|
189
208
|
|
|
190
209
|
### Advanced Search with Filters
|
|
210
|
+
|
|
191
211
|
```python
|
|
192
212
|
results = client.search({
|
|
193
213
|
'q': 'latest AI news',
|
|
@@ -198,6 +218,7 @@ results = client.search({
|
|
|
198
218
|
```
|
|
199
219
|
|
|
200
220
|
### Using SearchParams Object
|
|
221
|
+
|
|
201
222
|
```python
|
|
202
223
|
from serpex import SearchParams
|
|
203
224
|
|
|
@@ -212,6 +233,7 @@ results = client.search(params)
|
|
|
212
233
|
### Extract Web Content to LLM-Ready Data
|
|
213
234
|
|
|
214
235
|
#### Extract from a Single URL
|
|
236
|
+
|
|
215
237
|
```python
|
|
216
238
|
# Extract content from one website
|
|
217
239
|
result = client.extract({
|
|
@@ -224,6 +246,7 @@ if result.results[0].success:
|
|
|
224
246
|
```
|
|
225
247
|
|
|
226
248
|
#### Extract from Multiple URLs (up to 10 at once)
|
|
249
|
+
|
|
227
250
|
```python
|
|
228
251
|
# Extract content from multiple websites (up to 10 URLs)
|
|
229
252
|
extract_results = client.extract({
|
|
@@ -246,6 +269,7 @@ for result in extract_results.results:
|
|
|
246
269
|
```
|
|
247
270
|
|
|
248
271
|
#### Sample Response
|
|
272
|
+
|
|
249
273
|
```python
|
|
250
274
|
# Example response structure
|
|
251
275
|
{
|
|
@@ -271,6 +295,7 @@ for result in extract_results.results:
|
|
|
271
295
|
```
|
|
272
296
|
|
|
273
297
|
### Using ExtractParams Object
|
|
298
|
+
|
|
274
299
|
```python
|
|
275
300
|
from serpex import ExtractParams
|
|
276
301
|
|
|
@@ -288,4 +313,4 @@ results = client.extract(params)
|
|
|
288
313
|
|
|
289
314
|
## License
|
|
290
315
|
|
|
291
|
-
MIT
|
|
316
|
+
MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "serpex"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.3.0"
|
|
8
8
|
description = "Official Python SDK for Serpex Search API - Fetch search results in JSON format"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Serpex Team", email = "support@serpex.dev"}
|
|
@@ -5,13 +5,13 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="serpex",
|
|
8
|
-
version="2.
|
|
8
|
+
version="2.3.0",
|
|
9
9
|
author="Serpex Team",
|
|
10
10
|
author_email="support@serpex.dev",
|
|
11
11
|
description="Official Python SDK for Serpex SERP API - Fetch search results in JSON format",
|
|
12
12
|
long_description=long_description,
|
|
13
13
|
long_description_content_type="text/markdown",
|
|
14
|
-
url="https://github.com/divyeshradadiya/
|
|
14
|
+
url="https://github.com/divyeshradadiya/serpex-sdk-python",
|
|
15
15
|
packages=find_packages(where="src"),
|
|
16
16
|
package_dir={"": "src"},
|
|
17
17
|
classifiers=[
|
|
@@ -45,8 +45,8 @@ setup(
|
|
|
45
45
|
},
|
|
46
46
|
keywords="serp search api google search-results seo python sdk",
|
|
47
47
|
project_urls={
|
|
48
|
-
"Bug Reports": "https://github.com/divyeshradadiya/
|
|
49
|
-
"Source": "https://github.com/divyeshradadiya/
|
|
50
|
-
"Documentation": "https://github.com/divyeshradadiya/
|
|
48
|
+
"Bug Reports": "https://github.com/divyeshradadiya/serpex-sdk-python/issues",
|
|
49
|
+
"Source": "https://github.com/divyeshradadiya/serpex-sdk-python",
|
|
50
|
+
"Documentation": "https://github.com/divyeshradadiya/serpex-sdk-python#readme",
|
|
51
51
|
},
|
|
52
|
-
)
|
|
52
|
+
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: serpex
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Official Python SDK for Serpex Search API - Fetch search results in JSON format
|
|
5
|
-
Home-page: https://github.com/divyeshradadiya/
|
|
5
|
+
Home-page: https://github.com/divyeshradadiya/serpex-sdk-python
|
|
6
6
|
Author: Serpex Team
|
|
7
7
|
Author-email: Serpex Team <support@serpex.dev>
|
|
8
8
|
License: MIT
|
|
@@ -162,16 +162,34 @@ class SearchParams:
|
|
|
162
162
|
# Optional: Engine selection (defaults to 'auto')
|
|
163
163
|
engine: Optional[str] = 'auto'
|
|
164
164
|
|
|
165
|
-
# Optional: Search category (
|
|
166
|
-
category: Optional[str] = 'web'
|
|
165
|
+
# Optional: Search category ('web' for general search, 'news' for news articles - always returns latest news)
|
|
166
|
+
category: Optional[str] = 'web' # Supports: 'web', 'news'
|
|
167
167
|
|
|
168
|
-
# Optional: Time range filter
|
|
168
|
+
# Optional: Time range filter (only applicable for 'web' category, ignored for 'news')
|
|
169
169
|
time_range: Optional[str] = 'all'
|
|
170
170
|
|
|
171
171
|
# Optional: Response format
|
|
172
172
|
format: Optional[str] = 'json'
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
### News Search Example
|
|
176
|
+
|
|
177
|
+
News search always returns the latest news articles. The `time_range` parameter is ignored for news searches.
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Search for latest news articles
|
|
181
|
+
news_results = client.search({
|
|
182
|
+
'q': 'artificial intelligence',
|
|
183
|
+
'engine': 'google',
|
|
184
|
+
'category': 'news' # Always returns latest news
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
print(news_results.results[0].title)
|
|
188
|
+
print(news_results.results[0].published_date)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
````
|
|
192
|
+
|
|
175
193
|
## Supported Engines
|
|
176
194
|
|
|
177
195
|
- **auto**: Automatically routes to the best available search engine
|
|
@@ -196,7 +214,7 @@ class SearchResponse:
|
|
|
196
214
|
corrections: List[str]
|
|
197
215
|
infoboxes: List[Any]
|
|
198
216
|
suggestions: List[str]
|
|
199
|
-
|
|
217
|
+
````
|
|
200
218
|
|
|
201
219
|
## Error Handling
|
|
202
220
|
|
|
@@ -216,6 +234,7 @@ except SerpApiException as e:
|
|
|
216
234
|
## Examples
|
|
217
235
|
|
|
218
236
|
### Basic Search
|
|
237
|
+
|
|
219
238
|
```python
|
|
220
239
|
results = client.search({
|
|
221
240
|
'q': 'coffee shops near me'
|
|
@@ -223,6 +242,7 @@ results = client.search({
|
|
|
223
242
|
```
|
|
224
243
|
|
|
225
244
|
### Advanced Search with Filters
|
|
245
|
+
|
|
226
246
|
```python
|
|
227
247
|
results = client.search({
|
|
228
248
|
'q': 'latest AI news',
|
|
@@ -233,6 +253,7 @@ results = client.search({
|
|
|
233
253
|
```
|
|
234
254
|
|
|
235
255
|
### Using SearchParams Object
|
|
256
|
+
|
|
236
257
|
```python
|
|
237
258
|
from serpex import SearchParams
|
|
238
259
|
|
|
@@ -247,6 +268,7 @@ results = client.search(params)
|
|
|
247
268
|
### Extract Web Content to LLM-Ready Data
|
|
248
269
|
|
|
249
270
|
#### Extract from a Single URL
|
|
271
|
+
|
|
250
272
|
```python
|
|
251
273
|
# Extract content from one website
|
|
252
274
|
result = client.extract({
|
|
@@ -259,6 +281,7 @@ if result.results[0].success:
|
|
|
259
281
|
```
|
|
260
282
|
|
|
261
283
|
#### Extract from Multiple URLs (up to 10 at once)
|
|
284
|
+
|
|
262
285
|
```python
|
|
263
286
|
# Extract content from multiple websites (up to 10 URLs)
|
|
264
287
|
extract_results = client.extract({
|
|
@@ -281,6 +304,7 @@ for result in extract_results.results:
|
|
|
281
304
|
```
|
|
282
305
|
|
|
283
306
|
#### Sample Response
|
|
307
|
+
|
|
284
308
|
```python
|
|
285
309
|
# Example response structure
|
|
286
310
|
{
|
|
@@ -306,6 +330,7 @@ for result in extract_results.results:
|
|
|
306
330
|
```
|
|
307
331
|
|
|
308
332
|
### Using ExtractParams Object
|
|
333
|
+
|
|
309
334
|
```python
|
|
310
335
|
from serpex import ExtractParams
|
|
311
336
|
|
|
@@ -6,7 +6,14 @@ import requests
|
|
|
6
6
|
from typing import Optional, Dict, Any, Union
|
|
7
7
|
from urllib.parse import urlencode
|
|
8
8
|
|
|
9
|
-
from .types import
|
|
9
|
+
from .types import (
|
|
10
|
+
SearchResponse,
|
|
11
|
+
SearchParams,
|
|
12
|
+
ExtractResponse,
|
|
13
|
+
ExtractParams,
|
|
14
|
+
ExtractResult,
|
|
15
|
+
ExtractMetadata,
|
|
16
|
+
)
|
|
10
17
|
from .exceptions import SerpApiException
|
|
11
18
|
|
|
12
19
|
|
|
@@ -35,12 +42,16 @@ class SerpexClient:
|
|
|
35
42
|
self.api_key = api_key
|
|
36
43
|
self.base_url = base_url.rstrip("/")
|
|
37
44
|
self.session = requests.Session()
|
|
38
|
-
self.session.headers.update(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
self.session.headers.update(
|
|
46
|
+
{
|
|
47
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
}
|
|
50
|
+
)
|
|
42
51
|
|
|
43
|
-
def _make_request(
|
|
52
|
+
def _make_request(
|
|
53
|
+
self, params: Dict[str, Any], endpoint: str = "/api/search", method: str = "GET"
|
|
54
|
+
) -> Dict[str, Any]:
|
|
44
55
|
"""
|
|
45
56
|
Make an authenticated request to the API.
|
|
46
57
|
|
|
@@ -77,7 +88,7 @@ class SerpexClient:
|
|
|
77
88
|
query_string = urlencode(filtered_params, doseq=True)
|
|
78
89
|
final_url = f"{url}?{query_string}" if query_string else url
|
|
79
90
|
response = self.session.get(final_url, timeout=30)
|
|
80
|
-
|
|
91
|
+
|
|
81
92
|
return self._handle_response(response)
|
|
82
93
|
except requests.RequestException as e:
|
|
83
94
|
raise SerpApiException(f"Request failed: {str(e)}")
|
|
@@ -105,9 +116,7 @@ class SerpexClient:
|
|
|
105
116
|
try:
|
|
106
117
|
data = response.json()
|
|
107
118
|
raise SerpApiException(
|
|
108
|
-
data.get("error", "Validation error"),
|
|
109
|
-
status_code=400,
|
|
110
|
-
details=data
|
|
119
|
+
data.get("error", "Validation error"), status_code=400, details=data
|
|
111
120
|
)
|
|
112
121
|
except ValueError:
|
|
113
122
|
raise SerpApiException("Bad request", status_code=400)
|
|
@@ -117,12 +126,11 @@ class SerpexClient:
|
|
|
117
126
|
raise SerpApiException(
|
|
118
127
|
data.get("error", f"API error: {response.reason}"),
|
|
119
128
|
status_code=response.status_code,
|
|
120
|
-
details=data
|
|
129
|
+
details=data,
|
|
121
130
|
)
|
|
122
131
|
except ValueError:
|
|
123
132
|
raise SerpApiException(
|
|
124
|
-
f"API error: {response.reason}",
|
|
125
|
-
status_code=response.status_code
|
|
133
|
+
f"API error: {response.reason}", status_code=response.status_code
|
|
126
134
|
)
|
|
127
135
|
|
|
128
136
|
try:
|
|
@@ -150,21 +158,30 @@ class SerpexClient:
|
|
|
150
158
|
|
|
151
159
|
# Validate required parameters
|
|
152
160
|
if not params.q or not isinstance(params.q, str) or not params.q.strip():
|
|
153
|
-
raise ValueError(
|
|
161
|
+
raise ValueError(
|
|
162
|
+
"Query parameter (q) is required and must be a non-empty string"
|
|
163
|
+
)
|
|
154
164
|
|
|
155
165
|
if len(params.q) > 500:
|
|
156
166
|
raise ValueError("Query too long (max 500 characters)")
|
|
157
167
|
|
|
168
|
+
# Determine endpoint based on category
|
|
169
|
+
category = params.category or "web"
|
|
170
|
+
endpoint = "/api/search/news" if category == "news" else "/api/search"
|
|
171
|
+
|
|
158
172
|
# Prepare request parameters with only supported params
|
|
159
173
|
request_params = {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'time_range': params.time_range or 'all',
|
|
164
|
-
'format': params.format or 'json'
|
|
174
|
+
"q": params.q,
|
|
175
|
+
"engine": params.engine or "auto",
|
|
176
|
+
"format": params.format or "json",
|
|
165
177
|
}
|
|
166
178
|
|
|
167
|
-
|
|
179
|
+
# Add category for web search, omit for news (news endpoint doesn't need it)
|
|
180
|
+
if category == "web":
|
|
181
|
+
request_params["category"] = "web"
|
|
182
|
+
request_params["time_range"] = params.time_range or "all"
|
|
183
|
+
|
|
184
|
+
data = self._make_request(request_params, endpoint=endpoint)
|
|
168
185
|
|
|
169
186
|
# Convert response to SearchResponse object
|
|
170
187
|
from .types import SearchResult, SearchMetadata
|
|
@@ -178,10 +195,10 @@ class SerpexClient:
|
|
|
178
195
|
query=data["query"],
|
|
179
196
|
engines=data["engines"],
|
|
180
197
|
results=results,
|
|
181
|
-
answers=data
|
|
182
|
-
corrections=data
|
|
183
|
-
infoboxes=data
|
|
184
|
-
suggestions=data
|
|
198
|
+
answers=data.get("answers", []),
|
|
199
|
+
corrections=data.get("corrections", []),
|
|
200
|
+
infoboxes=data.get("infoboxes", []),
|
|
201
|
+
suggestions=data.get("suggestions", []),
|
|
185
202
|
)
|
|
186
203
|
|
|
187
204
|
def extract(self, params: Union[ExtractParams, Dict[str, Any]]) -> ExtractResponse:
|
|
@@ -203,7 +220,11 @@ class SerpexClient:
|
|
|
203
220
|
params = ExtractParams(**params)
|
|
204
221
|
|
|
205
222
|
# Validate required parameters
|
|
206
|
-
if
|
|
223
|
+
if (
|
|
224
|
+
not params.urls
|
|
225
|
+
or not isinstance(params.urls, list)
|
|
226
|
+
or len(params.urls) == 0
|
|
227
|
+
):
|
|
207
228
|
raise ValueError("URLs list is required and must contain at least one URL")
|
|
208
229
|
|
|
209
230
|
if len(params.urls) > 10:
|
|
@@ -217,6 +238,7 @@ class SerpexClient:
|
|
|
217
238
|
continue
|
|
218
239
|
try:
|
|
219
240
|
from urllib.parse import urlparse
|
|
241
|
+
|
|
220
242
|
parsed = urlparse(url)
|
|
221
243
|
if not parsed.scheme or not parsed.netloc:
|
|
222
244
|
invalid_urls.append(url)
|
|
@@ -227,11 +249,9 @@ class SerpexClient:
|
|
|
227
249
|
raise ValueError(f"Invalid URLs provided: {invalid_urls}")
|
|
228
250
|
|
|
229
251
|
# Prepare request parameters
|
|
230
|
-
request_params = {
|
|
231
|
-
'urls': params.urls
|
|
232
|
-
}
|
|
252
|
+
request_params = {"urls": params.urls}
|
|
233
253
|
|
|
234
|
-
data = self._make_request(request_params, endpoint=
|
|
254
|
+
data = self._make_request(request_params, endpoint="/api/crawl", method="POST")
|
|
235
255
|
|
|
236
256
|
# Convert response to ExtractResponse object
|
|
237
257
|
metadata = ExtractMetadata(**data["metadata"])
|
|
@@ -241,4 +261,4 @@ class SerpexClient:
|
|
|
241
261
|
success=data["success"],
|
|
242
262
|
results=results,
|
|
243
263
|
metadata=metadata,
|
|
244
|
-
)
|
|
264
|
+
)
|
|
@@ -9,6 +9,7 @@ from dataclasses import dataclass
|
|
|
9
9
|
@dataclass
|
|
10
10
|
class SearchResult:
|
|
11
11
|
"""Represents a single search result."""
|
|
12
|
+
|
|
12
13
|
title: str
|
|
13
14
|
url: str
|
|
14
15
|
snippet: str
|
|
@@ -23,15 +24,18 @@ class SearchResult:
|
|
|
23
24
|
@dataclass
|
|
24
25
|
class SearchMetadata:
|
|
25
26
|
"""Metadata for search results."""
|
|
27
|
+
|
|
26
28
|
number_of_results: int
|
|
27
29
|
response_time: int
|
|
28
30
|
timestamp: str
|
|
29
31
|
credits_used: int
|
|
32
|
+
category: Optional[str] = None # Optional category field for news searches
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
@dataclass
|
|
33
36
|
class SearchResponse:
|
|
34
37
|
"""Complete search response."""
|
|
38
|
+
|
|
35
39
|
metadata: SearchMetadata
|
|
36
40
|
id: str
|
|
37
41
|
query: str
|
|
@@ -46,6 +50,7 @@ class SearchResponse:
|
|
|
46
50
|
@dataclass
|
|
47
51
|
class ExtractResult:
|
|
48
52
|
"""Represents a single extraction result."""
|
|
53
|
+
|
|
49
54
|
url: str
|
|
50
55
|
success: bool
|
|
51
56
|
markdown: Optional[str] = None
|
|
@@ -59,6 +64,7 @@ class ExtractResult:
|
|
|
59
64
|
@dataclass
|
|
60
65
|
class ExtractMetadata:
|
|
61
66
|
"""Metadata for extraction results."""
|
|
67
|
+
|
|
62
68
|
total_urls: int
|
|
63
69
|
processed_urls: int
|
|
64
70
|
successful_crawls: int
|
|
@@ -71,6 +77,7 @@ class ExtractMetadata:
|
|
|
71
77
|
@dataclass
|
|
72
78
|
class ExtractResponse:
|
|
73
79
|
"""Complete extraction response."""
|
|
80
|
+
|
|
74
81
|
success: bool
|
|
75
82
|
results: List[ExtractResult]
|
|
76
83
|
metadata: ExtractMetadata
|
|
@@ -79,6 +86,7 @@ class ExtractResponse:
|
|
|
79
86
|
@dataclass
|
|
80
87
|
class ExtractParams:
|
|
81
88
|
"""Parameters for extraction requests."""
|
|
89
|
+
|
|
82
90
|
# Required: URLs to extract (max 10)
|
|
83
91
|
urls: List[str]
|
|
84
92
|
|
|
@@ -86,17 +94,18 @@ class ExtractParams:
|
|
|
86
94
|
@dataclass
|
|
87
95
|
class SearchParams:
|
|
88
96
|
"""Parameters for search requests."""
|
|
97
|
+
|
|
89
98
|
# Required: search query
|
|
90
99
|
q: str
|
|
91
100
|
|
|
92
101
|
# Optional: Engine selection (defaults to 'auto')
|
|
93
|
-
engine: Optional[str] =
|
|
102
|
+
engine: Optional[str] = "auto"
|
|
94
103
|
|
|
95
|
-
# Optional: Search category (
|
|
96
|
-
category: Optional[str] = 'web'
|
|
104
|
+
# Optional: Search category ('web' for general search, 'news' for news articles - always returns latest news)
|
|
105
|
+
category: Optional[str] = "web" # Supports: 'web', 'news'
|
|
97
106
|
|
|
98
|
-
# Optional: Time range filter
|
|
99
|
-
time_range: Optional[str] =
|
|
107
|
+
# Optional: Time range filter (only applicable for 'web' category, ignored for 'news')
|
|
108
|
+
time_range: Optional[str] = "all"
|
|
100
109
|
|
|
101
110
|
# Optional: Response format
|
|
102
|
-
format: Optional[str] =
|
|
111
|
+
format: Optional[str] = "json"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|