search-api-webui 0.1.6__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- search_api_webui/__init__.py +0 -1
- search_api_webui/app.py +142 -47
- search_api_webui/providers/__init__.py +10 -7
- search_api_webui/providers/base.py +65 -5
- search_api_webui/providers/generic.py +70 -43
- search_api_webui/providers/querit.py +42 -33
- search_api_webui/providers.yaml +62 -4
- search_api_webui/ruff.toml +27 -0
- search_api_webui/static/AppIcon.icns +0 -0
- search_api_webui/static/assets/{index-Co_gG-wr.js → index-7iEn12Q9.js} +39 -39
- search_api_webui/static/assets/index-DKxNoLrm.css +1 -0
- search_api_webui/static/index.html +2 -2
- {search_api_webui-0.1.6.dist-info → search_api_webui-0.1.8.dist-info}/METADATA +34 -12
- search_api_webui-0.1.8.dist-info/RECORD +18 -0
- search_api_webui/static/assets/index-BNPOSv2e.css +0 -1
- search_api_webui-0.1.6.dist-info/RECORD +0 -16
- {search_api_webui-0.1.6.dist-info → search_api_webui-0.1.8.dist-info}/WHEEL +0 -0
- {search_api_webui-0.1.6.dist-info → search_api_webui-0.1.8.dist-info}/entry_points.txt +0 -0
- {search_api_webui-0.1.6.dist-info → search_api_webui-0.1.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -18,32 +18,32 @@
|
|
|
18
18
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
19
19
|
# DEALINGS IN THE SOFTWARE.
|
|
20
20
|
|
|
21
|
-
import time
|
|
22
21
|
import json
|
|
22
|
+
import time
|
|
23
|
+
|
|
23
24
|
from querit import QueritClient
|
|
24
|
-
from querit.models.request import SearchRequest
|
|
25
25
|
from querit.errors import QueritError
|
|
26
|
-
from .
|
|
26
|
+
from querit.models.request import SearchRequest
|
|
27
|
+
|
|
28
|
+
from .base import BaseProvider, parse_server_latency
|
|
29
|
+
|
|
27
30
|
|
|
28
31
|
class QueritSdkProvider(BaseProvider):
|
|
29
|
-
|
|
32
|
+
'''
|
|
30
33
|
Specialized provider implementation using the official Querit Python SDK.
|
|
31
|
-
|
|
34
|
+
'''
|
|
32
35
|
|
|
33
36
|
def __init__(self, config):
|
|
34
37
|
self.config = config
|
|
35
38
|
|
|
36
39
|
def search(self, query, api_key, **kwargs):
|
|
37
|
-
|
|
40
|
+
'''
|
|
38
41
|
Executes a search using the Querit SDK.
|
|
39
42
|
Handles the 'Bearer' prefix logic internally within the SDK.
|
|
40
|
-
|
|
43
|
+
'''
|
|
41
44
|
try:
|
|
42
45
|
# Initialize client with the raw API key
|
|
43
|
-
client = QueritClient(
|
|
44
|
-
api_key=api_key.strip(),
|
|
45
|
-
timeout=30
|
|
46
|
-
)
|
|
46
|
+
client = QueritClient(api_key=api_key.strip(), timeout=30)
|
|
47
47
|
|
|
48
48
|
limit = int(kwargs.get('limit', 10))
|
|
49
49
|
|
|
@@ -55,10 +55,10 @@ class QueritSdkProvider(BaseProvider):
|
|
|
55
55
|
print(f'[Querit SDK] Searching: {query} (Limit: {limit})')
|
|
56
56
|
|
|
57
57
|
start_time = time.time()
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
# Execute search via SDK
|
|
60
60
|
response = client.search(request_model)
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
end_time = time.time()
|
|
63
63
|
|
|
64
64
|
# Normalize results to standard format
|
|
@@ -66,35 +66,44 @@ class QueritSdkProvider(BaseProvider):
|
|
|
66
66
|
if response.results:
|
|
67
67
|
for item in response.results:
|
|
68
68
|
# Use getattr to safely access SDK object attributes
|
|
69
|
-
normalized_results.append(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
normalized_results.append(
|
|
70
|
+
{
|
|
71
|
+
'title': getattr(item, 'title', ''),
|
|
72
|
+
'url': getattr(item, 'url', ''),
|
|
73
|
+
# Fallback to description if snippet is missing
|
|
74
|
+
'snippet': getattr(item, 'snippet', '') or getattr(item, 'description', ''),
|
|
75
|
+
},
|
|
76
|
+
)
|
|
75
77
|
|
|
76
78
|
# Calculate estimated size for metrics (approximate JSON size)
|
|
77
|
-
estimated_size = len(json.dumps(
|
|
79
|
+
estimated_size = len(json.dumps(list(normalized_results)))
|
|
80
|
+
|
|
81
|
+
# Extract server latency from SDK response if available
|
|
82
|
+
server_latency_ms = None
|
|
83
|
+
# The SDK may provide the server's 'took' field from the response
|
|
84
|
+
if hasattr(response, 'took') and response.took is not None:
|
|
85
|
+
server_latency_ms = parse_server_latency(response.took)
|
|
78
86
|
|
|
79
87
|
return {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
'results': normalized_results,
|
|
89
|
+
'metrics': {
|
|
90
|
+
'latency_ms': round((end_time - start_time) * 1000, 2),
|
|
91
|
+
'server_latency_ms': server_latency_ms,
|
|
92
|
+
'size_bytes': estimated_size,
|
|
93
|
+
},
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
except QueritError as e:
|
|
88
|
-
print(f
|
|
97
|
+
print(f'Querit SDK Error: {e}')
|
|
89
98
|
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
'error': f'Querit SDK Error: {str(e)}',
|
|
100
|
+
'results': [],
|
|
101
|
+
'metrics': {'latency_ms': 0, 'server_latency_ms': None, 'size_bytes': 0},
|
|
93
102
|
}
|
|
94
103
|
except Exception as e:
|
|
95
|
-
print(f
|
|
104
|
+
print(f'Unexpected Error: {e}')
|
|
96
105
|
return {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
'error': f'Error: {str(e)}',
|
|
107
|
+
'results': [],
|
|
108
|
+
'metrics': {'latency_ms': 0, 'server_latency_ms': None, 'size_bytes': 0},
|
|
100
109
|
}
|
search_api_webui/providers.yaml
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
querit:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
url: "https://api.querit.ai/v1/search"
|
|
3
|
+
method: "POST"
|
|
4
|
+
headers:
|
|
5
|
+
"Accept": "application/json"
|
|
6
|
+
"Authorization": "Bearer {api_key}"
|
|
7
|
+
"Content-Type": "application/json"
|
|
8
|
+
payload:
|
|
9
|
+
query: "{query}"
|
|
10
|
+
response_mapping:
|
|
11
|
+
root_path: "results.result"
|
|
12
|
+
server_latency_path: "took"
|
|
13
|
+
fields:
|
|
14
|
+
title: "title"
|
|
15
|
+
url: "url"
|
|
16
|
+
snippet: "snippet"
|
|
17
|
+
site_name: "site_name"
|
|
18
|
+
site_icon: "site_icon"
|
|
19
|
+
page_age: "page_age"
|
|
5
20
|
|
|
6
21
|
you:
|
|
7
22
|
url: "https://ydc-index.io/v1/search"
|
|
@@ -12,8 +27,51 @@ you:
|
|
|
12
27
|
query: "{query}"
|
|
13
28
|
payload: {}
|
|
14
29
|
response_mapping:
|
|
15
|
-
root_path: "results.web"
|
|
30
|
+
root_path: "results.web"
|
|
31
|
+
server_latency_path: "metadata.latency"
|
|
16
32
|
fields:
|
|
17
33
|
title: "title"
|
|
18
34
|
url: "url"
|
|
19
35
|
snippet: "snippets[0] || description"
|
|
36
|
+
site_icon: "favicon_url"
|
|
37
|
+
page_age: "page_age"
|
|
38
|
+
|
|
39
|
+
brave:
|
|
40
|
+
url: "https://api.search.brave.com/res/v1/web/search"
|
|
41
|
+
method: "GET"
|
|
42
|
+
headers:
|
|
43
|
+
X-Subscription-Token: "{api_key}"
|
|
44
|
+
Accept: "application/json"
|
|
45
|
+
params:
|
|
46
|
+
q: "{query}"
|
|
47
|
+
payload: {}
|
|
48
|
+
response_mapping:
|
|
49
|
+
root_path: "web.results"
|
|
50
|
+
fields:
|
|
51
|
+
title: "title"
|
|
52
|
+
url: "url"
|
|
53
|
+
snippet: "description"
|
|
54
|
+
page_age: "page_age"
|
|
55
|
+
|
|
56
|
+
exa:
|
|
57
|
+
url: "https://api.exa.ai/search"
|
|
58
|
+
method: "POST"
|
|
59
|
+
headers:
|
|
60
|
+
"Content-Type": "application/json"
|
|
61
|
+
"x-api-key": "{api_key}"
|
|
62
|
+
params: {}
|
|
63
|
+
payload:
|
|
64
|
+
query: "{query}"
|
|
65
|
+
response_mapping:
|
|
66
|
+
root_path: "results"
|
|
67
|
+
fields:
|
|
68
|
+
title: "title"
|
|
69
|
+
url: "url"
|
|
70
|
+
snippet: "text"
|
|
71
|
+
page_age: "publishedDate"
|
|
72
|
+
site_icon: "favicon"
|
|
73
|
+
|
|
74
|
+
querit_sdk:
|
|
75
|
+
type: "querit_sdk"
|
|
76
|
+
description: "Official Querit Search via Python SDK"
|
|
77
|
+
default_limit: 10
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Ruff configuration
|
|
2
|
+
# Ruff replaces Black, flake8, and isort
|
|
3
|
+
|
|
4
|
+
line-length = 120
|
|
5
|
+
target-version = "py37"
|
|
6
|
+
|
|
7
|
+
[format]
|
|
8
|
+
quote-style = "single"
|
|
9
|
+
indent-style = "space"
|
|
10
|
+
docstring-code-format = false
|
|
11
|
+
|
|
12
|
+
[lint]
|
|
13
|
+
select = [
|
|
14
|
+
"E", # pycodestyle errors
|
|
15
|
+
"W", # pycodestyle warnings
|
|
16
|
+
"F", # pyflakes
|
|
17
|
+
"I", # isort
|
|
18
|
+
"N", # pep8-naming
|
|
19
|
+
"UP", # pyupgrade
|
|
20
|
+
"B", # flake8-bugbear
|
|
21
|
+
"C4", # flake8-comprehensions
|
|
22
|
+
"SIM", # flake8-simplify
|
|
23
|
+
"COM", # flake8-commas (trailing commas)
|
|
24
|
+
]
|
|
25
|
+
ignore = [
|
|
26
|
+
"E203", # whitespace before ':' - conflicts with Black
|
|
27
|
+
]
|
|
Binary file
|