search-api-webui 0.1.1__py3-none-any.whl → 0.1.3__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.
@@ -1,11 +1,18 @@
1
1
  import json
2
2
  import os
3
+ import webbrowser
4
+ from pathlib import Path
3
5
  from flask import Flask, request, jsonify, send_from_directory
4
6
  from flask_cors import CORS
5
- from backend.providers import load_providers
7
+ from search_api_webui.providers import load_providers
6
8
 
7
9
  CURRENT_DIR = Path(__file__).resolve().parent
10
+
8
11
  STATIC_FOLDER = CURRENT_DIR / 'static'
12
+ if not STATIC_FOLDER.exists():
13
+ DEV_FRONTEND_DIST = CURRENT_DIR.parent / 'frontend' / 'dist'
14
+ if DEV_FRONTEND_DIST.exists():
15
+ STATIC_FOLDER = DEV_FRONTEND_DIST
9
16
 
10
17
  app = Flask(__name__, static_folder='static')
11
18
  CORS(app)
@@ -150,15 +157,18 @@ def main():
150
157
  import argparse
151
158
  parser = argparse.ArgumentParser(description="Search API WebUI")
152
159
  parser.add_argument("--port", type=int, default=8889, help="Port to run the server on")
153
- parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to run the server on")
160
+ parser.add_argument("--host", type=str, default="127.0.0.1", help="Host to run the server on")
154
161
  args = parser.parse_args()
155
162
 
163
+ url = f"http://{args.host}:{args.port}"
156
164
  print(f"Starting Search API WebUI...")
157
165
  print(f" - Config Storage: {USER_CONFIG_JSON}")
158
- print(f" - Serving on: http://{args.host}:{args.port}")
166
+ print(f" - Serving on: {url}")
167
+
168
+ # Open browser automatically after a short delay to ensure server is ready
169
+ webbrowser.open(url)
159
170
 
160
171
  app.run(host=args.host, port=args.port)
161
172
 
162
173
  if __name__ == "__main__":
163
174
  main()
164
-
@@ -26,7 +26,7 @@ def load_providers(file_path='providers.yaml'):
26
26
  provider_type = conf.get('type', 'generic')
27
27
 
28
28
  # Instantiate specific provider based on type or name
29
- if name == 'querit' or provider_type == 'querit_sdk':
29
+ if provider_type == 'querit_sdk':
30
30
  providers[name] = QueritSdkProvider(conf)
31
31
  else:
32
32
  providers[name] = GenericProvider(conf)
@@ -17,6 +17,9 @@ class GenericProvider(BaseProvider):
17
17
  config (dict): Configuration containing url, headers, params, and mapping rules.
18
18
  """
19
19
  self.config = config
20
+ self.session = requests.Session() # Persistent connection session
21
+ self._connection_ready = False # Connection ready status
22
+ self._last_url = None # Last used URL tracker
20
23
 
21
24
  def _fill_template(self, template_obj, **kwargs):
22
25
  """
@@ -42,6 +45,31 @@ class GenericProvider(BaseProvider):
42
45
  return {k: self._fill_template(v, **kwargs) for k, v in template_obj.items()}
43
46
  return template_obj
44
47
 
48
+ def _ensure_connection(self, url, headers):
49
+ """
50
+ Pre-warm HTTPS connection and verify availability.
51
+ Uses lightweight HEAD request to verify connection without fetching response body.
52
+
53
+ Args:
54
+ url (str): Target URL
55
+ headers (dict): Request headers
56
+
57
+ Returns:
58
+ bool: Whether connection is ready
59
+ """
60
+ # Re-warm if URL changed or connection not ready
61
+ if url != self._last_url or not self._connection_ready:
62
+ try:
63
+ # Verify connection using HEAD request (no response body)
64
+ self.session.head(url, headers=headers, timeout=5)
65
+ self._connection_ready = True
66
+ self._last_url = url
67
+ print(f' [Connection Pool] Connected to: {url}')
68
+ except Exception as e:
69
+ self._connection_ready = False
70
+ print(f' [Connection Pool] Connection warm-up failed: {e}')
71
+ raise
72
+
45
73
  def search(self, query, api_key, **kwargs):
46
74
  # 1. Extract parameters with defaults
47
75
  limit = kwargs.get('limit', '10')
@@ -69,6 +97,18 @@ class GenericProvider(BaseProvider):
69
97
  print(f'[{self.config.get("name", "Unknown")}] Search:')
70
98
  print(f' URL: {url} | Method: {method}')
71
99
 
100
+ # Ensure connection is pre-warmed (use HEAD request to verify availability)
101
+ # Pre-warming is not counted in request latency, only verifies connection
102
+ try:
103
+ self._ensure_connection(url, headers)
104
+ except Exception as e:
105
+ print(f"Connection Warm-up Error: {e}")
106
+ return {
107
+ "error": f"Connection failed: {str(e)}",
108
+ "results": [],
109
+ "metrics": {"latency_ms": 0, "size_bytes": 0}
110
+ }
111
+
72
112
  start_time = time.time()
73
113
 
74
114
  try:
@@ -78,10 +118,11 @@ class GenericProvider(BaseProvider):
78
118
  if json_body:
79
119
  req_args['json'] = json_body
80
120
 
121
+ # Use Session to send request (connection is reused)
81
122
  if method.upper() == 'GET':
82
- response = requests.get(url, **req_args)
123
+ response = self.session.get(url, **req_args)
83
124
  else:
84
- response = requests.post(url, **req_args)
125
+ response = self.session.post(url, **req_args)
85
126
 
86
127
  response.raise_for_status()
87
128
  except Exception as e:
@@ -1,7 +1,18 @@
1
1
  querit:
2
- type: "querit_sdk"
3
- description: "Official Querit Search via Python SDK"
4
- default_limit: 10
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
+ fields:
13
+ title: "title"
14
+ url: "url"
15
+ snippet: "snippet"
5
16
 
6
17
  ydc_search:
7
18
  url: "https://ydc-index.io/v1/search"
@@ -17,3 +28,8 @@ ydc_search:
17
28
  title: "title"
18
29
  url: "url"
19
30
  snippet: "snippets[0] || description"
31
+
32
+ querit_sdk:
33
+ type: "querit_sdk"
34
+ description: "Official Querit Search via Python SDK"
35
+ default_limit: 10
Binary file
@@ -3,6 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
6
7
  <title>Search API WebUI</title>
7
8
  <script type="module" crossorigin src="/assets/index-CF13bI2g.js"></script>
8
9
  <link rel="stylesheet" crossorigin href="/assets/index-DLyBd1PD.css">
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: search-api-webui
3
+ Version: 0.1.3
4
+ Summary: A Search API WebUI for Querit, You, and other search providers.
5
+ Project-URL: Homepage, https://github.com/querit-ai/search-api-webui
6
+ Project-URL: Repository, https://github.com/querit-ai/search-api-webui.git
7
+ Project-URL: Issues, https://github.com/querit-ai/search-api-webui/issues
8
+ Author: querit.ai
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,llm,querit,search,tool,webui
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Framework :: Flask
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Requires-Python: >=3.7
17
+ Requires-Dist: flask-cors
18
+ Requires-Dist: flask>=2.0.0
19
+ Requires-Dist: jmespath
20
+ Requires-Dist: pyyaml>=6.0
21
+ Requires-Dist: querit
22
+ Requires-Dist: requests>=2.25.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Search API WebUI
26
+
27
+ A lightweight, local WebUI for testing and visualizing Search APIs (Querit, You, etc.).
28
+
29
+ (images)
30
+
31
+ ## Features
32
+
33
+ * **Search**: Support for [Querit.ai](https://www.querit.ai/en/docs/reference/post), [You.com](https://docs.you.com/api-reference/search/v1-search), and generic Search APIs via configuration.
34
+ * **Performance Metrics**: Real-time display of request latency and payload size.
35
+ * **Visual Rendering**: Renders standard search results (Title, Snippet, URL) in a clean card layout.
36
+ * **Configurable**: Easy-to-edit providers.yaml to add or modify search providers.
37
+ * **Secure**: API Keys are stored locally in your $HOME folder.
38
+ ## Installation
39
+
40
+ Use this method if you just want to run the tool without modifying the code.
41
+
42
+ ### Prerequisites
43
+
44
+ Python 3.7+
45
+ ### Install via Pip
46
+
47
+ ```
48
+ pip install search-api-webui
49
+ ```
50
+
51
+ ### Run the Server
52
+
53
+ ```
54
+ search-api-webui
55
+ ```
56
+
57
+ Open your browser at http://localhost:8889.
58
+
59
+ ## Development
60
+
61
+ Use this method if you want to contribute to the code or build from source.
62
+
63
+ ### Prerequisites
64
+
65
+ Python 3.7+
66
+ Node.js & npm (for building the frontend)
67
+ ### Setup Steps
68
+
69
+ **Clone the repository**
70
+ ```
71
+ git clone https://github.com/querit-ai/search-api-webui.git
72
+ cd search-api-webui
73
+ ```
74
+
75
+ **Build Frontend**
76
+ ```
77
+ cd frontend
78
+ npm install
79
+ npm run build
80
+ cd …
81
+ ```
82
+
83
+ **Install Backend (Editable Mode)**
84
+ ```
85
+ pip install -e .
86
+ ```
87
+
88
+ **Run the Server**
89
+ ```
90
+ python -m backend.app
91
+ ```
92
+
93
+ ## Configuration
94
+
95
+ ### Add API Keys
96
+
97
+ Open the WebUI settings page (click the gear icon).
98
+ Enter your API Key for the selected provider (e.g., Querit).
99
+ Keys are saved locally in user_config.json.
100
+ ### Add New Providers
101
+
102
+ Edit providers.yaml in the root directory to add custom API endpoints. The system uses JMESPath to map JSON responses to the UI.
103
+
104
+ ```
105
+ my_custom_search:
106
+ url: “https://api.example.com/search”
107
+ method: “GET”
108
+ headers:
109
+ Authorization: “Bearer {api_key}”
110
+ params:
111
+ q: “{query}”
112
+ response_mapping:
113
+ root_path: “data.items”
114
+ fields:
115
+ title: “title”
116
+ url: “link”
117
+ snippet: “snippet”
118
+ ```
119
+
120
+ ## License
121
+
122
+ MIT License. See LICENSE for details.
@@ -0,0 +1,16 @@
1
+ search_api_webui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ search_api_webui/app.py,sha256=GsPD0tEsXvQnlryYWmwtsYaVPdgJulF8DrhAWeRC3Ao,5470
3
+ search_api_webui/providers.yaml,sha256=GMF7-o9eqe1AVXuMHEfdfl4OPeIZInDCqjsvO2tRHp0,752
4
+ search_api_webui/providers/__init__.py,sha256=1RfIA8eQxDLDjXrUxWzmg3tucZGv7WuZ5pJBsc6fAnQ,1052
5
+ search_api_webui/providers/base.py,sha256=_iYcxCxI7VCoxb02D71KqtojAU91D6rc3c5dwKNYJ2o,863
6
+ search_api_webui/providers/generic.py,sha256=ztwqko1KjiC2BS2afwZY2heREWLW0Kh2ZivqgLofbXU,6211
7
+ search_api_webui/providers/querit.py,sha256=5_vHXcDz59jhqY35w8vaoVH3BqGiQCYEZaekIvTKkak,2688
8
+ search_api_webui/static/favicon.ico,sha256=U_7TbOXM0jf963y9j0jogM0rBpKNr72HVVOofnBNAVQ,15086
9
+ search_api_webui/static/index.html,sha256=XpFSxOK7-zs_c4AmgSadEjBiAkAsSju2O275UrGMuBM,465
10
+ search_api_webui/static/assets/index-CF13bI2g.js,sha256=91wc8meWvRXloy4vzmGN43DvrpHIjMVIdCihXCw9zBU,208926
11
+ search_api_webui/static/assets/index-DLyBd1PD.css,sha256=nevUEbN7Fw9cq3aXWV7v_tQpD00d7kr3I64dgZ-e7ys,17914
12
+ search_api_webui-0.1.3.dist-info/METADATA,sha256=soEZ1eYNQ4QT1Fst0WA50vOrGHzQXCNYKqmY_6Bvibs,2924
13
+ search_api_webui-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ search_api_webui-0.1.3.dist-info/entry_points.txt,sha256=ogYy3eeonZ_oQlrEZC-4JBWfYdB7kkkdqXUUmX0xgMs,63
15
+ search_api_webui-0.1.3.dist-info/licenses/LICENSE,sha256=jHhlLwtvhZRz1yU1G_3cjsPigCTXQGT1qshhyekdmTE,1061
16
+ search_api_webui-0.1.3.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ search-api-webui = search_api_webui.app:main
@@ -1,93 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: search-api-webui
3
- Version: 0.1.1
4
- Summary: A Search API WebUI for Querit, You, and other search providers.
5
- Project-URL: Homepage, https://github.com/querit-ai/search-api-webui
6
- Project-URL: Repository, https://github.com/querit-ai/search-api-webui.git
7
- Project-URL: Issues, https://github.com/querit-ai/search-api-webui/issues
8
- Author: Search API WebUI Team
9
- License: MIT
10
- License-File: LICENSE
11
- Keywords: api,llm,querit,search,tool,webui
12
- Classifier: Development Status :: 3 - Alpha
13
- Classifier: Framework :: Flask
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Requires-Python: >=3.7
17
- Requires-Dist: flask-cors
18
- Requires-Dist: flask>=2.0.0
19
- Requires-Dist: jmespath
20
- Requires-Dist: pyyaml>=6.0
21
- Requires-Dist: querit
22
- Requires-Dist: requests>=2.25.0
23
- Description-Content-Type: text/markdown
24
-
25
- # Search API WebUI
26
-
27
- A lightweight, local WebUI for testing and visualizing Search APIs (Querit, YDC, etc.).
28
-
29
- ## Features
30
-
31
- - 🔍 **Search**: Support for Querit, You.com, and generic Search APIs via configuration.
32
- - ⚡ **Performance Metrics**: Real-time display of request latency and payload size.
33
- - 🎨 **Visual Rendering**: Renders standard search results (Title, Snippet, URL) in a clean card layout.
34
- - 🛠️ **Configurable**: Easy-to-edit `providers.yaml` to add or modify search providers.
35
- - 🔒 **Secure**: API Keys are stored locally in `user_config.json` and never committed.
36
-
37
- ## Quick Start
38
-
39
- ### Prerequisites
40
-
41
- - Python 3.7+
42
- - Node.js & npm (for building the frontend)
43
-
44
- ### Installation
45
-
46
- 1. **Clone the repository**
47
- ```bash
48
- git clone https://github.com/querit-ai/search-api-webui.git
49
- cd search-api-webui
50
- ```
51
- 2. **Build Frontend**
52
- ```bash
53
- cd frontend
54
- npm install
55
- npm run build
56
- cd ..
57
- ```
58
- 3. **Install Backend**
59
- ```bash
60
- pip install -e .
61
- ```
62
-
63
- ### Usage
64
- **Run the server:**
65
- ```bash
66
- python -m backend.app
67
- ```
68
- Or if you installed via pip:
69
- ```bash
70
- search-api-webui
71
- ```
72
-
73
- Open your browser at http://localhost:8889.
74
-
75
- ## Configuration
76
- ### Add API Keys
77
- 1. Open the WebUI settings page.
78
- 2. Enter your API Key for the selected provider (e.g., Querit).
79
- 3. Keys are saved locally in user_config.json.
80
-
81
- ### Add New Providers
82
- Edit providers.yaml to add custom API endpoints. The system uses JMESPath to map JSON responses to the UI.
83
- ```yaml
84
- my_custom_search:
85
- url: "https://api.example.com/search"
86
- method: "GET"
87
- ...
88
- ```
89
- ## Development
90
- Backend: Flask (in backend/)
91
- Frontend: React + Vite (in frontend/)
92
- ## License
93
- MIT License. See LICENSE for details.
@@ -1,15 +0,0 @@
1
- backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- backend/app.py,sha256=6sKid3996ydT19Q04Eg0RY23PEJb0TIGWz_FRIxCDI8,5119
3
- backend/providers/__init__.py,sha256=l9SCd9sEISWZB-E2Co8ds2hILaxBVoh2S6SSg7MXXIo,1072
4
- backend/providers/base.py,sha256=_iYcxCxI7VCoxb02D71KqtojAU91D6rc3c5dwKNYJ2o,863
5
- backend/providers/generic.py,sha256=3dyx3Hpbo4hlfUcwy1wYt5N5dc2X3fK1iFnOoT3m_Vc,4440
6
- backend/providers/querit.py,sha256=5_vHXcDz59jhqY35w8vaoVH3BqGiQCYEZaekIvTKkak,2688
7
- backend/providers.yaml,sha256=2aRmfT7NmeU9IfUqX7phRjOf_fUACRD5ondYJO2HH4I,400
8
- backend/static/index.html,sha256=fhLWDY2W-bN-bBq2fmkch-e6gRZpoyqbKvNBzpWHiHk,401
9
- backend/static/assets/index-CF13bI2g.js,sha256=91wc8meWvRXloy4vzmGN43DvrpHIjMVIdCihXCw9zBU,208926
10
- backend/static/assets/index-DLyBd1PD.css,sha256=nevUEbN7Fw9cq3aXWV7v_tQpD00d7kr3I64dgZ-e7ys,17914
11
- search_api_webui-0.1.1.dist-info/METADATA,sha256=b1YR8TsTbezT2uXKEYQFFcjA4aPqK9OFEBreHoIFiO8,2577
12
- search_api_webui-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
- search_api_webui-0.1.1.dist-info/entry_points.txt,sha256=D9R5N6s2Bt8rEKYSINTUB1f45nH-Xc5iIKNPfYYc8ec,54
14
- search_api_webui-0.1.1.dist-info/licenses/LICENSE,sha256=jHhlLwtvhZRz1yU1G_3cjsPigCTXQGT1qshhyekdmTE,1061
15
- search_api_webui-0.1.1.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- search-api-webui = backend.app:main
File without changes
File without changes
File without changes