serpex 2.0.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.0.0/LICENSE +21 -0
- serpex-2.0.0/PKG-INFO +197 -0
- serpex-2.0.0/README.md +162 -0
- serpex-2.0.0/pyproject.toml +45 -0
- serpex-2.0.0/setup.cfg +4 -0
- serpex-2.0.0/setup.py +52 -0
- serpex-2.0.0/src/serpex.egg-info/PKG-INFO +197 -0
- serpex-2.0.0/src/serpex.egg-info/SOURCES.txt +13 -0
- serpex-2.0.0/src/serpex.egg-info/dependency_links.txt +1 -0
- serpex-2.0.0/src/serpex.egg-info/requires.txt +4 -0
- serpex-2.0.0/src/serpex.egg-info/top_level.txt +1 -0
- serpex-2.0.0/src/serpex_sdk/__init__.py +12 -0
- serpex-2.0.0/src/serpex_sdk/client.py +186 -0
- serpex-2.0.0/src/serpex_sdk/exceptions.py +40 -0
- serpex-2.0.0/src/serpex_sdk/types.py +81 -0
serpex-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Serpex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
serpex-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: serpex
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Official Python SDK for Serpex SERP API - Fetch search results in JSON format
|
|
5
|
+
Home-page: https://github.com/divyeshradadiya/serp-frontend
|
|
6
|
+
Author: Serpex Team
|
|
7
|
+
Author-email: Serpex Team <support@serpex.dev>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/divyeshradadiya/serp-frontend
|
|
10
|
+
Project-URL: Repository, https://github.com/divyeshradadiya/serp-frontend
|
|
11
|
+
Project-URL: Bug Reports, https://github.com/divyeshradadiya/serp-frontend/issues
|
|
12
|
+
Project-URL: Documentation, https://github.com/divyeshradadiya/serp-frontend#readme
|
|
13
|
+
Keywords: serp,search,api,google,search-results,seo,python,sdk
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: requests>=2.25.0
|
|
30
|
+
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
31
|
+
Dynamic: author
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: requires-python
|
|
35
|
+
|
|
36
|
+
# serpex
|
|
37
|
+
|
|
38
|
+
Official Python SDK for the Serpex SERP API - Fetch search results in JSON format.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install serpex
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or with poetry:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
poetry add serpex
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from serpex import SerpApiClient
|
|
56
|
+
|
|
57
|
+
# Initialize the client with your API key
|
|
58
|
+
client = SerpApiClient('your-api-key-here')
|
|
59
|
+
|
|
60
|
+
# Search using a dictionary (recommended for simple use cases)
|
|
61
|
+
results = client.search({
|
|
62
|
+
'q': 'python tutorial',
|
|
63
|
+
'engine': 'google',
|
|
64
|
+
'language': 'en'
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
# Or using SearchParams object for type safety
|
|
68
|
+
from serpex import SearchParams
|
|
69
|
+
|
|
70
|
+
params = SearchParams(q='python tutorial', engine='google', language='en')
|
|
71
|
+
results = client.search(params)
|
|
72
|
+
|
|
73
|
+
print(results.results)
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API Reference
|
|
78
|
+
|
|
79
|
+
### SerpApiClient
|
|
80
|
+
|
|
81
|
+
#### Constructor
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
SerpApiClient(api_key: str, base_url: str = "https://api.serpex.dev")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- `api_key`: Your API key from the Serpex dashboard
|
|
88
|
+
- `base_url`: Optional base URL (defaults to 'https://api.serpex.dev')
|
|
89
|
+
|
|
90
|
+
#### Methods
|
|
91
|
+
|
|
92
|
+
##### `search(params: SearchParams | Dict[str, Any]) -> SearchResponse`
|
|
93
|
+
|
|
94
|
+
Search using the SERP API with flexible parameters. Accepts either a SearchParams object or a dictionary. Engine parameter is required.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
# Using dictionary (simple approach)
|
|
98
|
+
results = client.search({
|
|
99
|
+
'q': 'javascript frameworks',
|
|
100
|
+
'engine': 'brave',
|
|
101
|
+
'category': 'search',
|
|
102
|
+
'country': 'US'
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
# Using SearchParams object (type-safe approach)
|
|
106
|
+
from serpex import SearchParams
|
|
107
|
+
|
|
108
|
+
params = SearchParams(
|
|
109
|
+
q='javascript frameworks',
|
|
110
|
+
engine='brave',
|
|
111
|
+
category='search',
|
|
112
|
+
country='US'
|
|
113
|
+
)
|
|
114
|
+
results = client.search(params)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Search Parameters
|
|
118
|
+
|
|
119
|
+
The `SearchParams` dataclass supports all search parameters:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
@dataclass
|
|
123
|
+
class SearchParams:
|
|
124
|
+
# Required: query (use either q or query)
|
|
125
|
+
q: Optional[str] = None
|
|
126
|
+
query: Optional[str] = None
|
|
127
|
+
|
|
128
|
+
# Engine selection (only one engine allowed)
|
|
129
|
+
engine: Optional[str] = None
|
|
130
|
+
|
|
131
|
+
# Common parameters
|
|
132
|
+
language: Optional[str] = None
|
|
133
|
+
pageno: Optional[int] = None
|
|
134
|
+
page: Optional[int] = None
|
|
135
|
+
time_range: Optional[str] = None
|
|
136
|
+
safesearch: Optional[int] = None
|
|
137
|
+
|
|
138
|
+
# Google specific
|
|
139
|
+
hl: Optional[str] = None # language
|
|
140
|
+
lr: Optional[str] = None # language restrict
|
|
141
|
+
cr: Optional[str] = None # country restrict
|
|
142
|
+
|
|
143
|
+
# Bing specific
|
|
144
|
+
mkt: Optional[str] = None # market
|
|
145
|
+
|
|
146
|
+
# DuckDuckGo specific
|
|
147
|
+
region: Optional[str] = None
|
|
148
|
+
|
|
149
|
+
# Brave specific
|
|
150
|
+
category: Optional[str] = None
|
|
151
|
+
spellcheck: Optional[bool] = None
|
|
152
|
+
ui_lang: Optional[str] = None
|
|
153
|
+
country: Optional[str] = None
|
|
154
|
+
|
|
155
|
+
# Legacy support
|
|
156
|
+
maxResults: Optional[int] = None
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Response Format
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
@dataclass
|
|
163
|
+
class SearchResponse:
|
|
164
|
+
metadata: SearchMetadata
|
|
165
|
+
id: str
|
|
166
|
+
query: str
|
|
167
|
+
engines: List[str]
|
|
168
|
+
results: List[SearchResult]
|
|
169
|
+
answers: List[Any]
|
|
170
|
+
corrections: List[str]
|
|
171
|
+
infoboxes: List[Any]
|
|
172
|
+
suggestions: List[str]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Error Handling
|
|
176
|
+
|
|
177
|
+
The SDK raises `SerpApiException` for API errors:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from serpex import SerpApiClient, SerpApiException
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
results = client.search(SearchParams(q='test query'))
|
|
184
|
+
except SerpApiException as e:
|
|
185
|
+
print(f"API error: {e}")
|
|
186
|
+
print(f"Status code: {e.status_code}")
|
|
187
|
+
print(f"Details: {e.details}")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Requirements
|
|
191
|
+
|
|
192
|
+
- Python 3.8+
|
|
193
|
+
- requests
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
serpex-2.0.0/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# serpex
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the Serpex SERP API - Fetch search results in JSON format.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install serpex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or with poetry:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
poetry add serpex
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from serpex import SerpApiClient
|
|
21
|
+
|
|
22
|
+
# Initialize the client with your API key
|
|
23
|
+
client = SerpApiClient('your-api-key-here')
|
|
24
|
+
|
|
25
|
+
# Search using a dictionary (recommended for simple use cases)
|
|
26
|
+
results = client.search({
|
|
27
|
+
'q': 'python tutorial',
|
|
28
|
+
'engine': 'google',
|
|
29
|
+
'language': 'en'
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
# Or using SearchParams object for type safety
|
|
33
|
+
from serpex import SearchParams
|
|
34
|
+
|
|
35
|
+
params = SearchParams(q='python tutorial', engine='google', language='en')
|
|
36
|
+
results = client.search(params)
|
|
37
|
+
|
|
38
|
+
print(results.results)
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### SerpApiClient
|
|
45
|
+
|
|
46
|
+
#### Constructor
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
SerpApiClient(api_key: str, base_url: str = "https://api.serpex.dev")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- `api_key`: Your API key from the Serpex dashboard
|
|
53
|
+
- `base_url`: Optional base URL (defaults to 'https://api.serpex.dev')
|
|
54
|
+
|
|
55
|
+
#### Methods
|
|
56
|
+
|
|
57
|
+
##### `search(params: SearchParams | Dict[str, Any]) -> SearchResponse`
|
|
58
|
+
|
|
59
|
+
Search using the SERP API with flexible parameters. Accepts either a SearchParams object or a dictionary. Engine parameter is required.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# Using dictionary (simple approach)
|
|
63
|
+
results = client.search({
|
|
64
|
+
'q': 'javascript frameworks',
|
|
65
|
+
'engine': 'brave',
|
|
66
|
+
'category': 'search',
|
|
67
|
+
'country': 'US'
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
# Using SearchParams object (type-safe approach)
|
|
71
|
+
from serpex import SearchParams
|
|
72
|
+
|
|
73
|
+
params = SearchParams(
|
|
74
|
+
q='javascript frameworks',
|
|
75
|
+
engine='brave',
|
|
76
|
+
category='search',
|
|
77
|
+
country='US'
|
|
78
|
+
)
|
|
79
|
+
results = client.search(params)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Search Parameters
|
|
83
|
+
|
|
84
|
+
The `SearchParams` dataclass supports all search parameters:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
@dataclass
|
|
88
|
+
class SearchParams:
|
|
89
|
+
# Required: query (use either q or query)
|
|
90
|
+
q: Optional[str] = None
|
|
91
|
+
query: Optional[str] = None
|
|
92
|
+
|
|
93
|
+
# Engine selection (only one engine allowed)
|
|
94
|
+
engine: Optional[str] = None
|
|
95
|
+
|
|
96
|
+
# Common parameters
|
|
97
|
+
language: Optional[str] = None
|
|
98
|
+
pageno: Optional[int] = None
|
|
99
|
+
page: Optional[int] = None
|
|
100
|
+
time_range: Optional[str] = None
|
|
101
|
+
safesearch: Optional[int] = None
|
|
102
|
+
|
|
103
|
+
# Google specific
|
|
104
|
+
hl: Optional[str] = None # language
|
|
105
|
+
lr: Optional[str] = None # language restrict
|
|
106
|
+
cr: Optional[str] = None # country restrict
|
|
107
|
+
|
|
108
|
+
# Bing specific
|
|
109
|
+
mkt: Optional[str] = None # market
|
|
110
|
+
|
|
111
|
+
# DuckDuckGo specific
|
|
112
|
+
region: Optional[str] = None
|
|
113
|
+
|
|
114
|
+
# Brave specific
|
|
115
|
+
category: Optional[str] = None
|
|
116
|
+
spellcheck: Optional[bool] = None
|
|
117
|
+
ui_lang: Optional[str] = None
|
|
118
|
+
country: Optional[str] = None
|
|
119
|
+
|
|
120
|
+
# Legacy support
|
|
121
|
+
maxResults: Optional[int] = None
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Response Format
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
@dataclass
|
|
128
|
+
class SearchResponse:
|
|
129
|
+
metadata: SearchMetadata
|
|
130
|
+
id: str
|
|
131
|
+
query: str
|
|
132
|
+
engines: List[str]
|
|
133
|
+
results: List[SearchResult]
|
|
134
|
+
answers: List[Any]
|
|
135
|
+
corrections: List[str]
|
|
136
|
+
infoboxes: List[Any]
|
|
137
|
+
suggestions: List[str]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Error Handling
|
|
141
|
+
|
|
142
|
+
The SDK raises `SerpApiException` for API errors:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from serpex import SerpApiClient, SerpApiException
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
results = client.search(SearchParams(q='test query'))
|
|
149
|
+
except SerpApiException as e:
|
|
150
|
+
print(f"API error: {e}")
|
|
151
|
+
print(f"Status code: {e.status_code}")
|
|
152
|
+
print(f"Details: {e.details}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Requirements
|
|
156
|
+
|
|
157
|
+
- Python 3.8+
|
|
158
|
+
- requests
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "serpex"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "Official Python SDK for Serpex SERP API - Fetch search results in JSON format"
|
|
9
|
+
authors = [
|
|
10
|
+
{name = "Serpex Team", email = "support@serpex.dev"}
|
|
11
|
+
]
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
license = {text = "MIT"}
|
|
14
|
+
requires-python = ">=3.8"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
]
|
|
29
|
+
keywords = ["serp", "search", "api", "google", "search-results", "seo", "python", "sdk"]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"requests>=2.25.0",
|
|
32
|
+
"typing-extensions>=4.0.0; python_version<'3.10'",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/divyeshradadiya/serp-frontend"
|
|
37
|
+
Repository = "https://github.com/divyeshradadiya/serp-frontend"
|
|
38
|
+
"Bug Reports" = "https://github.com/divyeshradadiya/serp-frontend/issues"
|
|
39
|
+
Documentation = "https://github.com/divyeshradadiya/serp-frontend#readme"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["src"]
|
|
43
|
+
|
|
44
|
+
[tool.setuptools.package-dir]
|
|
45
|
+
"" = "src"
|
serpex-2.0.0/setup.cfg
ADDED
serpex-2.0.0/setup.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="serpex",
|
|
8
|
+
version="2.0.0",
|
|
9
|
+
author="Serpex Team",
|
|
10
|
+
author_email="support@serpex.dev",
|
|
11
|
+
description="Official Python SDK for Serpex SERP API - Fetch search results in JSON format",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/divyeshradadiya/serp-frontend",
|
|
15
|
+
packages=find_packages(where="src"),
|
|
16
|
+
package_dir={"": "src"},
|
|
17
|
+
classifiers=[
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.8",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
],
|
|
31
|
+
python_requires=">=3.8",
|
|
32
|
+
install_requires=[
|
|
33
|
+
"requests>=2.25.0",
|
|
34
|
+
"typing-extensions>=4.0.0; python_version<'3.10'",
|
|
35
|
+
],
|
|
36
|
+
extras_require={
|
|
37
|
+
"dev": [
|
|
38
|
+
"pytest>=6.0",
|
|
39
|
+
"pytest-asyncio>=0.21.0",
|
|
40
|
+
"black>=22.0.0",
|
|
41
|
+
"isort>=5.10.0",
|
|
42
|
+
"mypy>=0.950",
|
|
43
|
+
"flake8>=4.0.0",
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
keywords="serp search api google search-results seo python sdk",
|
|
47
|
+
project_urls={
|
|
48
|
+
"Bug Reports": "https://github.com/divyeshradadiya/serp-frontend/issues",
|
|
49
|
+
"Source": "https://github.com/divyeshradadiya/serp-frontend",
|
|
50
|
+
"Documentation": "https://github.com/divyeshradadiya/serp-frontend#readme",
|
|
51
|
+
},
|
|
52
|
+
)
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: serpex
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Official Python SDK for Serpex SERP API - Fetch search results in JSON format
|
|
5
|
+
Home-page: https://github.com/divyeshradadiya/serp-frontend
|
|
6
|
+
Author: Serpex Team
|
|
7
|
+
Author-email: Serpex Team <support@serpex.dev>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/divyeshradadiya/serp-frontend
|
|
10
|
+
Project-URL: Repository, https://github.com/divyeshradadiya/serp-frontend
|
|
11
|
+
Project-URL: Bug Reports, https://github.com/divyeshradadiya/serp-frontend/issues
|
|
12
|
+
Project-URL: Documentation, https://github.com/divyeshradadiya/serp-frontend#readme
|
|
13
|
+
Keywords: serp,search,api,google,search-results,seo,python,sdk
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: requests>=2.25.0
|
|
30
|
+
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
31
|
+
Dynamic: author
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: requires-python
|
|
35
|
+
|
|
36
|
+
# serpex
|
|
37
|
+
|
|
38
|
+
Official Python SDK for the Serpex SERP API - Fetch search results in JSON format.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install serpex
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or with poetry:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
poetry add serpex
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from serpex import SerpApiClient
|
|
56
|
+
|
|
57
|
+
# Initialize the client with your API key
|
|
58
|
+
client = SerpApiClient('your-api-key-here')
|
|
59
|
+
|
|
60
|
+
# Search using a dictionary (recommended for simple use cases)
|
|
61
|
+
results = client.search({
|
|
62
|
+
'q': 'python tutorial',
|
|
63
|
+
'engine': 'google',
|
|
64
|
+
'language': 'en'
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
# Or using SearchParams object for type safety
|
|
68
|
+
from serpex import SearchParams
|
|
69
|
+
|
|
70
|
+
params = SearchParams(q='python tutorial', engine='google', language='en')
|
|
71
|
+
results = client.search(params)
|
|
72
|
+
|
|
73
|
+
print(results.results)
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API Reference
|
|
78
|
+
|
|
79
|
+
### SerpApiClient
|
|
80
|
+
|
|
81
|
+
#### Constructor
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
SerpApiClient(api_key: str, base_url: str = "https://api.serpex.dev")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- `api_key`: Your API key from the Serpex dashboard
|
|
88
|
+
- `base_url`: Optional base URL (defaults to 'https://api.serpex.dev')
|
|
89
|
+
|
|
90
|
+
#### Methods
|
|
91
|
+
|
|
92
|
+
##### `search(params: SearchParams | Dict[str, Any]) -> SearchResponse`
|
|
93
|
+
|
|
94
|
+
Search using the SERP API with flexible parameters. Accepts either a SearchParams object or a dictionary. Engine parameter is required.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
# Using dictionary (simple approach)
|
|
98
|
+
results = client.search({
|
|
99
|
+
'q': 'javascript frameworks',
|
|
100
|
+
'engine': 'brave',
|
|
101
|
+
'category': 'search',
|
|
102
|
+
'country': 'US'
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
# Using SearchParams object (type-safe approach)
|
|
106
|
+
from serpex import SearchParams
|
|
107
|
+
|
|
108
|
+
params = SearchParams(
|
|
109
|
+
q='javascript frameworks',
|
|
110
|
+
engine='brave',
|
|
111
|
+
category='search',
|
|
112
|
+
country='US'
|
|
113
|
+
)
|
|
114
|
+
results = client.search(params)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Search Parameters
|
|
118
|
+
|
|
119
|
+
The `SearchParams` dataclass supports all search parameters:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
@dataclass
|
|
123
|
+
class SearchParams:
|
|
124
|
+
# Required: query (use either q or query)
|
|
125
|
+
q: Optional[str] = None
|
|
126
|
+
query: Optional[str] = None
|
|
127
|
+
|
|
128
|
+
# Engine selection (only one engine allowed)
|
|
129
|
+
engine: Optional[str] = None
|
|
130
|
+
|
|
131
|
+
# Common parameters
|
|
132
|
+
language: Optional[str] = None
|
|
133
|
+
pageno: Optional[int] = None
|
|
134
|
+
page: Optional[int] = None
|
|
135
|
+
time_range: Optional[str] = None
|
|
136
|
+
safesearch: Optional[int] = None
|
|
137
|
+
|
|
138
|
+
# Google specific
|
|
139
|
+
hl: Optional[str] = None # language
|
|
140
|
+
lr: Optional[str] = None # language restrict
|
|
141
|
+
cr: Optional[str] = None # country restrict
|
|
142
|
+
|
|
143
|
+
# Bing specific
|
|
144
|
+
mkt: Optional[str] = None # market
|
|
145
|
+
|
|
146
|
+
# DuckDuckGo specific
|
|
147
|
+
region: Optional[str] = None
|
|
148
|
+
|
|
149
|
+
# Brave specific
|
|
150
|
+
category: Optional[str] = None
|
|
151
|
+
spellcheck: Optional[bool] = None
|
|
152
|
+
ui_lang: Optional[str] = None
|
|
153
|
+
country: Optional[str] = None
|
|
154
|
+
|
|
155
|
+
# Legacy support
|
|
156
|
+
maxResults: Optional[int] = None
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Response Format
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
@dataclass
|
|
163
|
+
class SearchResponse:
|
|
164
|
+
metadata: SearchMetadata
|
|
165
|
+
id: str
|
|
166
|
+
query: str
|
|
167
|
+
engines: List[str]
|
|
168
|
+
results: List[SearchResult]
|
|
169
|
+
answers: List[Any]
|
|
170
|
+
corrections: List[str]
|
|
171
|
+
infoboxes: List[Any]
|
|
172
|
+
suggestions: List[str]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Error Handling
|
|
176
|
+
|
|
177
|
+
The SDK raises `SerpApiException` for API errors:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from serpex import SerpApiClient, SerpApiException
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
results = client.search(SearchParams(q='test query'))
|
|
184
|
+
except SerpApiException as e:
|
|
185
|
+
print(f"API error: {e}")
|
|
186
|
+
print(f"Status code: {e.status_code}")
|
|
187
|
+
print(f"Details: {e.details}")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Requirements
|
|
191
|
+
|
|
192
|
+
- Python 3.8+
|
|
193
|
+
- requests
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
src/serpex.egg-info/PKG-INFO
|
|
6
|
+
src/serpex.egg-info/SOURCES.txt
|
|
7
|
+
src/serpex.egg-info/dependency_links.txt
|
|
8
|
+
src/serpex.egg-info/requires.txt
|
|
9
|
+
src/serpex.egg-info/top_level.txt
|
|
10
|
+
src/serpex_sdk/__init__.py
|
|
11
|
+
src/serpex_sdk/client.py
|
|
12
|
+
src/serpex_sdk/exceptions.py
|
|
13
|
+
src/serpex_sdk/types.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
serpex_sdk
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Serpex SERP API Python SDK
|
|
3
|
+
|
|
4
|
+
Official Python SDK for the Serpex SERP API - Fetch search results in JSON format.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .client import SerpApiClient
|
|
8
|
+
from .exceptions import SerpApiException
|
|
9
|
+
from .types import SearchParams, SearchResponse
|
|
10
|
+
|
|
11
|
+
__version__ = "1.0.0"
|
|
12
|
+
__all__ = ["SerpApiClient", "SerpApiException", "SearchParams", "SearchResponse"]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main client for the Serpex SERP API Python SDK.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
from typing import Optional, Dict, Any, Union
|
|
7
|
+
from urllib.parse import urlencode
|
|
8
|
+
|
|
9
|
+
from .types import SearchResponse, SearchParams
|
|
10
|
+
from .exceptions import SerpApiException
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SerpApiClient:
|
|
14
|
+
"""
|
|
15
|
+
Official Python client for the Serpex SERP API.
|
|
16
|
+
|
|
17
|
+
Provides methods to interact with the Serpex SERP API for fetching
|
|
18
|
+
search results in JSON format from Google, Bing, DuckDuckGo, and Brave.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, api_key: str, base_url: str = "https://api.serpex.dev"):
|
|
22
|
+
"""
|
|
23
|
+
Initialize the SERP API client.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
api_key: Your API key from the Serpex dashboard
|
|
27
|
+
base_url: Base URL for the API (optional, defaults to production)
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
ValueError: If api_key is not provided or is not a string
|
|
31
|
+
"""
|
|
32
|
+
if not api_key or not isinstance(api_key, str):
|
|
33
|
+
raise ValueError("API key is required and must be a string")
|
|
34
|
+
|
|
35
|
+
self.api_key = api_key
|
|
36
|
+
self.base_url = base_url.rstrip("/")
|
|
37
|
+
self.session = requests.Session()
|
|
38
|
+
self.session.headers.update({
|
|
39
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
def _make_request(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
44
|
+
"""
|
|
45
|
+
Make an authenticated request to the API.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
params: Query parameters
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
JSON response data
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
SerpApiException: For API errors
|
|
55
|
+
"""
|
|
56
|
+
url = f"{self.base_url}/api/search"
|
|
57
|
+
|
|
58
|
+
# Filter out None values and prepare query parameters
|
|
59
|
+
filtered_params = {}
|
|
60
|
+
for key, value in params.items():
|
|
61
|
+
if value is not None:
|
|
62
|
+
if isinstance(value, list):
|
|
63
|
+
# Handle array parameters
|
|
64
|
+
filtered_params[key] = value
|
|
65
|
+
else:
|
|
66
|
+
filtered_params[key] = value
|
|
67
|
+
|
|
68
|
+
# Build query string
|
|
69
|
+
query_string = urlencode(filtered_params, doseq=True)
|
|
70
|
+
final_url = f"{url}?{query_string}" if query_string else url
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
response = self.session.get(final_url, timeout=30)
|
|
74
|
+
return self._handle_response(response)
|
|
75
|
+
except requests.RequestException as e:
|
|
76
|
+
raise SerpApiException(f"Request failed: {str(e)}")
|
|
77
|
+
|
|
78
|
+
def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
|
|
79
|
+
"""
|
|
80
|
+
Handle API response and raise appropriate exceptions for errors.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
response: Requests response object
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
JSON response data
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
SerpApiException: For various API errors
|
|
90
|
+
"""
|
|
91
|
+
if response.status_code == 401:
|
|
92
|
+
raise SerpApiException("Invalid API key", status_code=401)
|
|
93
|
+
elif response.status_code == 402:
|
|
94
|
+
raise SerpApiException("Insufficient credits", status_code=402)
|
|
95
|
+
elif response.status_code == 429:
|
|
96
|
+
raise SerpApiException("Rate limit exceeded", status_code=429)
|
|
97
|
+
elif response.status_code == 400:
|
|
98
|
+
try:
|
|
99
|
+
data = response.json()
|
|
100
|
+
raise SerpApiException(
|
|
101
|
+
data.get("error", "Validation error"),
|
|
102
|
+
status_code=400,
|
|
103
|
+
details=data
|
|
104
|
+
)
|
|
105
|
+
except ValueError:
|
|
106
|
+
raise SerpApiException("Bad request", status_code=400)
|
|
107
|
+
elif not response.ok:
|
|
108
|
+
try:
|
|
109
|
+
data = response.json()
|
|
110
|
+
raise SerpApiException(
|
|
111
|
+
data.get("error", f"API error: {response.reason}"),
|
|
112
|
+
status_code=response.status_code,
|
|
113
|
+
details=data
|
|
114
|
+
)
|
|
115
|
+
except ValueError:
|
|
116
|
+
raise SerpApiException(
|
|
117
|
+
f"API error: {response.reason}",
|
|
118
|
+
status_code=response.status_code
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
return response.json()
|
|
123
|
+
except ValueError:
|
|
124
|
+
raise SerpApiException("Invalid JSON response from API")
|
|
125
|
+
|
|
126
|
+
def search(self, params: Union[SearchParams, Dict[str, Any]]) -> SearchResponse:
|
|
127
|
+
"""
|
|
128
|
+
Search using the SERP API.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
params: SearchParams object or dictionary with query and options
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
SearchResponse object with results
|
|
135
|
+
|
|
136
|
+
Raises:
|
|
137
|
+
ValueError: If query is not provided
|
|
138
|
+
SerpApiException: For API errors
|
|
139
|
+
"""
|
|
140
|
+
# Convert dict to SearchParams if needed
|
|
141
|
+
if isinstance(params, dict):
|
|
142
|
+
params = SearchParams(**params)
|
|
143
|
+
|
|
144
|
+
# Validate required parameters
|
|
145
|
+
search_query = params.q or params.query
|
|
146
|
+
if not search_query or not isinstance(search_query, str) or not search_query.strip():
|
|
147
|
+
raise ValueError("Query parameter (q or query) is required and must be a non-empty string")
|
|
148
|
+
|
|
149
|
+
if len(search_query) > 500:
|
|
150
|
+
raise ValueError("Query too long (max 500 characters)")
|
|
151
|
+
|
|
152
|
+
# Prepare request parameters
|
|
153
|
+
request_params = {}
|
|
154
|
+
|
|
155
|
+
# Convert SearchParams to dict, excluding None values
|
|
156
|
+
for key, value in params.__dict__.items():
|
|
157
|
+
if value is not None:
|
|
158
|
+
request_params[key] = value
|
|
159
|
+
|
|
160
|
+
# Ensure we have a query parameter
|
|
161
|
+
request_params['q'] = search_query
|
|
162
|
+
|
|
163
|
+
# Handle engine parameter - must be specified
|
|
164
|
+
if not params.engine:
|
|
165
|
+
raise ValueError('Engine parameter is required (google, bing, duckduckgo, or brave)')
|
|
166
|
+
request_params['engine'] = params.engine
|
|
167
|
+
|
|
168
|
+
data = self._make_request(request_params)
|
|
169
|
+
|
|
170
|
+
# Convert response to SearchResponse object
|
|
171
|
+
from .types import SearchResult, SearchMetadata
|
|
172
|
+
|
|
173
|
+
metadata = SearchMetadata(**data["metadata"])
|
|
174
|
+
results = [SearchResult(**result) for result in data["results"]]
|
|
175
|
+
|
|
176
|
+
return SearchResponse(
|
|
177
|
+
metadata=metadata,
|
|
178
|
+
id=data["id"],
|
|
179
|
+
query=data["query"],
|
|
180
|
+
engines=data["engines"],
|
|
181
|
+
results=results,
|
|
182
|
+
answers=data["answers"],
|
|
183
|
+
corrections=data["corrections"],
|
|
184
|
+
infoboxes=data["infoboxes"],
|
|
185
|
+
suggestions=data["suggestions"],
|
|
186
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Exceptions for the Serpex SERP API Python SDK.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SerpApiException(Exception):
|
|
7
|
+
"""Base exception for SERP API errors."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str, status_code: int = None, details: dict = None):
|
|
10
|
+
super().__init__(message)
|
|
11
|
+
self.status_code = status_code
|
|
12
|
+
self.details = details or {}
|
|
13
|
+
|
|
14
|
+
def __str__(self):
|
|
15
|
+
if self.status_code:
|
|
16
|
+
return f"[{self.status_code}] {super().__str__()}"
|
|
17
|
+
return super().__str__()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AuthenticationError(SerpApiException):
|
|
21
|
+
"""Raised when authentication fails."""
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RateLimitError(SerpApiException):
|
|
26
|
+
"""Raised when rate limit is exceeded."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, message: str, retry_after: int = None, **kwargs):
|
|
29
|
+
super().__init__(message, **kwargs)
|
|
30
|
+
self.retry_after = retry_after
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class InsufficientCreditsError(SerpApiException):
|
|
34
|
+
"""Raised when there are insufficient credits."""
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ValidationError(SerpApiException):
|
|
39
|
+
"""Raised when request validation fails."""
|
|
40
|
+
pass
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type definitions for the Serpex SERP API Python SDK.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Optional, Dict, Any, Union
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class SearchResult:
|
|
11
|
+
"""Represents a single search result."""
|
|
12
|
+
title: str
|
|
13
|
+
url: str
|
|
14
|
+
snippet: str
|
|
15
|
+
position: int
|
|
16
|
+
engine: str
|
|
17
|
+
published_date: Optional[str] = None
|
|
18
|
+
img_src: Optional[str] = None
|
|
19
|
+
duration: Optional[str] = None
|
|
20
|
+
score: Optional[float] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class SearchMetadata:
|
|
25
|
+
"""Metadata for search results."""
|
|
26
|
+
number_of_results: int
|
|
27
|
+
response_time: int
|
|
28
|
+
timestamp: str
|
|
29
|
+
credits_used: int
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class SearchResponse:
|
|
34
|
+
"""Complete search response."""
|
|
35
|
+
metadata: SearchMetadata
|
|
36
|
+
id: str
|
|
37
|
+
query: str
|
|
38
|
+
engines: List[str]
|
|
39
|
+
results: List[SearchResult]
|
|
40
|
+
answers: List[Any]
|
|
41
|
+
corrections: List[str]
|
|
42
|
+
infoboxes: List[Any]
|
|
43
|
+
suggestions: List[str]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class SearchParams:
|
|
48
|
+
"""Parameters for search requests."""
|
|
49
|
+
# Required: query (use either q or query)
|
|
50
|
+
q: Optional[str] = None
|
|
51
|
+
query: Optional[str] = None
|
|
52
|
+
|
|
53
|
+
# Engine selection (only one engine allowed)
|
|
54
|
+
engine: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
# Common parameters
|
|
57
|
+
language: Optional[str] = None
|
|
58
|
+
pageno: Optional[int] = None
|
|
59
|
+
page: Optional[int] = None
|
|
60
|
+
time_range: Optional[str] = None
|
|
61
|
+
safesearch: Optional[int] = None
|
|
62
|
+
|
|
63
|
+
# Google specific
|
|
64
|
+
hl: Optional[str] = None # language
|
|
65
|
+
lr: Optional[str] = None # language restrict
|
|
66
|
+
cr: Optional[str] = None # country restrict
|
|
67
|
+
|
|
68
|
+
# Bing specific
|
|
69
|
+
mkt: Optional[str] = None # market
|
|
70
|
+
|
|
71
|
+
# DuckDuckGo specific
|
|
72
|
+
region: Optional[str] = None
|
|
73
|
+
|
|
74
|
+
# Brave specific
|
|
75
|
+
category: Optional[str] = None
|
|
76
|
+
spellcheck: Optional[bool] = None
|
|
77
|
+
ui_lang: Optional[str] = None
|
|
78
|
+
country: Optional[str] = None
|
|
79
|
+
|
|
80
|
+
# Legacy support
|
|
81
|
+
maxResults: Optional[int] = None
|