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 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
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
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,4 @@
1
+ requests>=2.25.0
2
+
3
+ [:python_version < "3.10"]
4
+ typing-extensions>=4.0.0
@@ -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