cazyundee commited on
Commit
b7ba30b
·
verified ·
1 Parent(s): c35e741

Use public SearXNG instances instead of bundling

Browse files
Files changed (1) hide show
  1. app.py +31 -46
app.py CHANGED
@@ -3,8 +3,6 @@ import platform
3
  import sys
4
  import shutil
5
  import tempfile
6
- import subprocess
7
- import time
8
  import threading
9
  import torch
10
  import spaces
@@ -208,58 +206,50 @@ def _get_runtime_specs():
208
 
209
 
210
  # ---------------------------------------------------------------------------
211
- # SearXNG local instance
212
  # ---------------------------------------------------------------------------
213
 
214
- SEARXNG_PORT = 8888
215
- SEARXNG_BASE = f"http://127.0.0.1:{SEARXNG_PORT}"
216
- _searxng_process = None
 
 
 
 
217
 
218
 
219
- def _start_searxng():
220
- """Start SearXNG as a background subprocess."""
221
- global _searxng_process
222
- settings_path = os.path.join(os.path.dirname(__file__), "searxng_settings.yml")
223
- if not os.path.exists(settings_path):
224
- _log("SearXNG settings not found, search disabled")
225
- return False
 
 
 
 
 
 
 
 
226
 
227
- try:
228
- _searxng_process = subprocess.Popen(
229
- [sys.executable, "-m", "searx.webapp"],
230
- env={**os.environ, "SEARXNG_SETTINGS_PATH": settings_path},
231
- stdout=subprocess.PIPE,
232
- stderr=subprocess.PIPE,
233
- )
234
- # Wait for SearXNG to start
235
- for _ in range(30):
236
- time.sleep(1)
237
- try:
238
- req = urllib.request.Request(
239
- f"{SEARXNG_BASE}/search?q=test&format=json",
240
- headers={"User-Agent": "RespiteAPI/1.0"},
241
- )
242
- urllib.request.urlopen(req, timeout=3)
243
- _log("SearXNG started successfully")
244
- return True
245
- except Exception:
246
- continue
247
- _log("SearXNG failed to start within 30s")
248
- return False
249
- except Exception as e:
250
- _log(f"SearXNG start failed: {e}")
251
- return False
252
 
253
 
254
  def _search_web(query, categories="general", max_results=10):
255
- """Query the local SearXNG instance."""
 
 
256
  params = {
257
  "q": query,
258
  "format": "json",
259
  "categories": categories,
260
  "language": "en",
261
  }
262
- url = f"{SEARXNG_BASE}/search?{urllib.parse.urlencode(params)}"
263
  req = urllib.request.Request(url, headers={"User-Agent": "RespiteAPI/1.0"})
264
  resp = urllib.request.urlopen(req, timeout=10)
265
  data = _json.loads(resp.read())
@@ -274,17 +264,12 @@ def _search_web(query, categories="general", max_results=10):
274
  })
275
  return {
276
  "query": query,
 
277
  "results": results,
278
  "total_results": len(data.get("results", [])),
279
- "categories": data.get("infoboxes", []),
280
  }
281
 
282
 
283
- # Start SearXNG in background thread so it doesn't block Gradio startup
284
- _searxng_thread = threading.Thread(target=_start_searxng, daemon=True)
285
- _searxng_thread.start()
286
-
287
-
288
  # ---------------------------------------------------------------------------
289
  # Model cache
290
  # ---------------------------------------------------------------------------
 
3
  import sys
4
  import shutil
5
  import tempfile
 
 
6
  import threading
7
  import torch
8
  import spaces
 
206
 
207
 
208
  # ---------------------------------------------------------------------------
209
+ # SearXNG search (uses public instances with JSON API)
210
  # ---------------------------------------------------------------------------
211
 
212
+ SEARXNG_INSTANCES = [
213
+ "https://search.ononoki.org",
214
+ "https://searx.be",
215
+ "https://search.sapti.me",
216
+ "https://searxng.site",
217
+ ]
218
+ _searxng_active_instance = None
219
 
220
 
221
+ def _probe_searxng_instances():
222
+ """Find a working SearXNG instance."""
223
+ global _searxng_active_instance
224
+ for instance in SEARXNG_INSTANCES:
225
+ try:
226
+ url = f"{instance}/search?q=test&format=json"
227
+ req = urllib.request.Request(url, headers={"User-Agent": "RespiteAPI/1.0"})
228
+ resp = urllib.request.urlopen(req, timeout=5)
229
+ _json.loads(resp.read())
230
+ _searxng_active_instance = instance
231
+ _log(f"SearXNG instance ready: {instance}")
232
+ return
233
+ except Exception:
234
+ continue
235
+ _log("Warning: No working SearXNG instance found")
236
 
237
+
238
+ # Probe instances in background so it doesn't block startup
239
+ threading.Thread(target=_probe_searxng_instances, daemon=True).start()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
 
242
  def _search_web(query, categories="general", max_results=10):
243
+ """Query a public SearXNG instance."""
244
+ if not _searxng_active_instance:
245
+ raise RuntimeError("No SearXNG instance available")
246
  params = {
247
  "q": query,
248
  "format": "json",
249
  "categories": categories,
250
  "language": "en",
251
  }
252
+ url = f"{_searxng_active_instance}/search?{urllib.parse.urlencode(params)}"
253
  req = urllib.request.Request(url, headers={"User-Agent": "RespiteAPI/1.0"})
254
  resp = urllib.request.urlopen(req, timeout=10)
255
  data = _json.loads(resp.read())
 
264
  })
265
  return {
266
  "query": query,
267
+ "instance": _searxng_active_instance,
268
  "results": results,
269
  "total_results": len(data.get("results", [])),
 
270
  }
271
 
272
 
 
 
 
 
 
273
  # ---------------------------------------------------------------------------
274
  # Model cache
275
  # ---------------------------------------------------------------------------