refac
This commit is contained in:
1 parent
23d03d6aae
commit
3a232f5e9a
3 files changed
+99
No files matched your search
@@ -0,0 +1,44 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
|
||||||
|
from open_webui.utils.session_pool import get_session
|
||||||
|
|
||||||
|
|
||||||
|
async def search_serphouse(
|
||||||
|
api_key: str,
|
||||||
|
domain: str,
|
||||||
|
query: str,
|
||||||
|
count: int,
|
||||||
|
filter_list: list[str | None] | None = None,
|
||||||
|
) -> list[SearchResult]:
|
||||||
|
"""Query SERPHouse and return normalised organic results."""
|
||||||
|
session = await get_session()
|
||||||
|
async with session.get(
|
||||||
|
'https://api.serphouse.com/serp/live',
|
||||||
|
params={
|
||||||
|
'q': query,
|
||||||
|
'domain': (domain or 'google.com').strip() or 'google.com',
|
||||||
|
'device': 'desktop',
|
||||||
|
'serp_type': 'web',
|
||||||
|
'page': 1,
|
||||||
|
'num_result': count,
|
||||||
|
},
|
||||||
|
headers={'Authorization': f'Bearer {api_key}', 'Accept': 'application/json'},
|
||||||
|
) as response:
|
||||||
|
response.raise_for_status()
|
||||||
|
payload = await response.json()
|
||||||
|
|
||||||
|
organic = payload.get('results', {}).get('results', {}).get('organic', [])
|
||||||
|
organic = sorted(organic, key=lambda item: item.get('position', 0))
|
||||||
|
if filter_list:
|
||||||
|
organic = get_filtered_results(organic, filter_list)
|
||||||
|
|
||||||
|
return [
|
||||||
|
SearchResult(
|
||||||
|
link=item.get('link', ''),
|
||||||
|
title=item.get('title'),
|
||||||
|
snippet=item.get('snippet'),
|
||||||
|
)
|
||||||
|
for item in organic[:count]
|
||||||
|
if item.get('link')
|
||||||
|
]
|
||||||
@@ -103,6 +103,7 @@ from open_webui.retrieval.web.searchapi import search_searchapi
|
|||||||
from open_webui.retrieval.web.searxng import search_searxng
|
from open_webui.retrieval.web.searxng import search_searxng
|
||||||
from open_webui.retrieval.web.serpapi import search_serpapi
|
from open_webui.retrieval.web.serpapi import search_serpapi
|
||||||
from open_webui.retrieval.web.serper import search_serper
|
from open_webui.retrieval.web.serper import search_serper
|
||||||
|
from open_webui.retrieval.web.serphouse import search_serphouse
|
||||||
from open_webui.retrieval.web.serply import search_serply
|
from open_webui.retrieval.web.serply import search_serply
|
||||||
from open_webui.retrieval.web.serpstack import search_serpstack
|
from open_webui.retrieval.web.serpstack import search_serpstack
|
||||||
from open_webui.retrieval.web.sougou import search_sougou
|
from open_webui.retrieval.web.sougou import search_sougou
|
||||||
@@ -357,6 +358,8 @@ RETRIEVAL_CONFIG_KEYS = {
|
|||||||
'SERPAPI_API_KEY': 'rag.web.search.serpapi_api_key',
|
'SERPAPI_API_KEY': 'rag.web.search.serpapi_api_key',
|
||||||
'SERPAPI_ENGINE': 'rag.web.search.serpapi_engine',
|
'SERPAPI_ENGINE': 'rag.web.search.serpapi_engine',
|
||||||
'SERPER_API_KEY': 'rag.web.search.serper_api_key',
|
'SERPER_API_KEY': 'rag.web.search.serper_api_key',
|
||||||
|
'SERPHOUSE_API_KEY': 'rag.web.search.serphouse_api_key',
|
||||||
|
'SERPHOUSE_DOMAIN': 'rag.web.search.serphouse_domain',
|
||||||
'SERPLY_API_KEY': 'rag.web.search.serply_api_key',
|
'SERPLY_API_KEY': 'rag.web.search.serply_api_key',
|
||||||
'SERPSTACK_API_KEY': 'rag.web.search.serpstack_api_key',
|
'SERPSTACK_API_KEY': 'rag.web.search.serpstack_api_key',
|
||||||
'SERPSTACK_HTTPS': 'rag.web.search.serpstack_https',
|
'SERPSTACK_HTTPS': 'rag.web.search.serpstack_https',
|
||||||
@@ -703,6 +706,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
|
|||||||
'SERPSTACK_API_KEY': config.SERPSTACK_API_KEY,
|
'SERPSTACK_API_KEY': config.SERPSTACK_API_KEY,
|
||||||
'SERPSTACK_HTTPS': config.SERPSTACK_HTTPS,
|
'SERPSTACK_HTTPS': config.SERPSTACK_HTTPS,
|
||||||
'SERPER_API_KEY': config.SERPER_API_KEY,
|
'SERPER_API_KEY': config.SERPER_API_KEY,
|
||||||
|
'SERPHOUSE_API_KEY': config.SERPHOUSE_API_KEY,
|
||||||
|
'SERPHOUSE_DOMAIN': config.SERPHOUSE_DOMAIN,
|
||||||
'SERPLY_API_KEY': config.SERPLY_API_KEY,
|
'SERPLY_API_KEY': config.SERPLY_API_KEY,
|
||||||
'DDGS_BACKEND': config.DDGS_BACKEND,
|
'DDGS_BACKEND': config.DDGS_BACKEND,
|
||||||
'TAVILY_API_KEY': config.TAVILY_API_KEY,
|
'TAVILY_API_KEY': config.TAVILY_API_KEY,
|
||||||
@@ -774,6 +779,8 @@ class WebConfig(BaseModel):
|
|||||||
SERPSTACK_API_KEY: str | None = None
|
SERPSTACK_API_KEY: str | None = None
|
||||||
SERPSTACK_HTTPS: bool | None = None
|
SERPSTACK_HTTPS: bool | None = None
|
||||||
SERPER_API_KEY: str | None = None
|
SERPER_API_KEY: str | None = None
|
||||||
|
SERPHOUSE_API_KEY: str | None = None
|
||||||
|
SERPHOUSE_DOMAIN: str | None = None
|
||||||
SERPLY_API_KEY: str | None = None
|
SERPLY_API_KEY: str | None = None
|
||||||
DDGS_BACKEND: str | None = None
|
DDGS_BACKEND: str | None = None
|
||||||
TAVILY_API_KEY: str | None = None
|
TAVILY_API_KEY: str | None = None
|
||||||
@@ -1273,6 +1280,8 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend
|
|||||||
config.SERPSTACK_API_KEY = form_data.web.SERPSTACK_API_KEY
|
config.SERPSTACK_API_KEY = form_data.web.SERPSTACK_API_KEY
|
||||||
config.SERPSTACK_HTTPS = form_data.web.SERPSTACK_HTTPS
|
config.SERPSTACK_HTTPS = form_data.web.SERPSTACK_HTTPS
|
||||||
config.SERPER_API_KEY = form_data.web.SERPER_API_KEY
|
config.SERPER_API_KEY = form_data.web.SERPER_API_KEY
|
||||||
|
config.SERPHOUSE_API_KEY = form_data.web.SERPHOUSE_API_KEY
|
||||||
|
config.SERPHOUSE_DOMAIN = form_data.web.SERPHOUSE_DOMAIN
|
||||||
config.SERPLY_API_KEY = form_data.web.SERPLY_API_KEY
|
config.SERPLY_API_KEY = form_data.web.SERPLY_API_KEY
|
||||||
config.DDGS_BACKEND = form_data.web.DDGS_BACKEND
|
config.DDGS_BACKEND = form_data.web.DDGS_BACKEND
|
||||||
config.TAVILY_API_KEY = form_data.web.TAVILY_API_KEY
|
config.TAVILY_API_KEY = form_data.web.TAVILY_API_KEY
|
||||||
@@ -1412,6 +1421,8 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend
|
|||||||
'SERPSTACK_API_KEY': config.SERPSTACK_API_KEY,
|
'SERPSTACK_API_KEY': config.SERPSTACK_API_KEY,
|
||||||
'SERPSTACK_HTTPS': config.SERPSTACK_HTTPS,
|
'SERPSTACK_HTTPS': config.SERPSTACK_HTTPS,
|
||||||
'SERPER_API_KEY': config.SERPER_API_KEY,
|
'SERPER_API_KEY': config.SERPER_API_KEY,
|
||||||
|
'SERPHOUSE_API_KEY': config.SERPHOUSE_API_KEY,
|
||||||
|
'SERPHOUSE_DOMAIN': config.SERPHOUSE_DOMAIN,
|
||||||
'SERPLY_API_KEY': config.SERPLY_API_KEY,
|
'SERPLY_API_KEY': config.SERPLY_API_KEY,
|
||||||
'TAVILY_API_KEY': config.TAVILY_API_KEY,
|
'TAVILY_API_KEY': config.TAVILY_API_KEY,
|
||||||
'SEARCHAPI_API_KEY': config.SEARCHAPI_API_KEY,
|
'SEARCHAPI_API_KEY': config.SEARCHAPI_API_KEY,
|
||||||
@@ -2259,6 +2270,17 @@ async def search_web(request: Request, engine: str, query: str, user=None) -> li
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise Exception('No SERPER_API_KEY found in environment variables')
|
raise Exception('No SERPER_API_KEY found in environment variables')
|
||||||
|
elif engine == 'serphouse':
|
||||||
|
if config.SERPHOUSE_API_KEY:
|
||||||
|
return await search_serphouse(
|
||||||
|
config.SERPHOUSE_API_KEY,
|
||||||
|
config.SERPHOUSE_DOMAIN,
|
||||||
|
query,
|
||||||
|
config.WEB_SEARCH_RESULT_COUNT,
|
||||||
|
config.WEB_SEARCH_DOMAIN_FILTER_LIST,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise Exception('No SERPHOUSE_API_KEY found in environment variables')
|
||||||
elif engine == 'serply':
|
elif engine == 'serply':
|
||||||
if config.SERPLY_API_KEY:
|
if config.SERPLY_API_KEY:
|
||||||
return await asyncio.to_thread(
|
return await asyncio.to_thread(
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
'bocha',
|
'bocha',
|
||||||
'serpstack',
|
'serpstack',
|
||||||
'serper',
|
'serper',
|
||||||
|
'serphouse',
|
||||||
'serply',
|
'serply',
|
||||||
'searchapi',
|
'searchapi',
|
||||||
'serpapi',
|
'serpapi',
|
||||||
@@ -180,6 +181,8 @@
|
|||||||
{#each webSearchEngines as engine}
|
{#each webSearchEngines as engine}
|
||||||
{#if engine === 'duckduckgo' || engine === 'ddgs'}
|
{#if engine === 'duckduckgo' || engine === 'ddgs'}
|
||||||
<option value={engine}>DDGS</option>
|
<option value={engine}>DDGS</option>
|
||||||
|
{:else if engine === 'serphouse'}
|
||||||
|
<option value={engine}>SERPHouse</option>
|
||||||
{:else}
|
{:else}
|
||||||
<option value={engine}>{engine}</option>
|
<option value={engine}>{engine}</option>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -470,6 +473,36 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{:else if webConfig.WEB_SEARCH_ENGINE === 'serphouse'}
|
||||||
|
<div class="mb-2.5 flex w-full flex-col">
|
||||||
|
<div>
|
||||||
|
<div class=" self-center text-xs font-medium mb-1">
|
||||||
|
{$i18n.t('SERPHouse API Key')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SensitiveInput
|
||||||
|
placeholder={$i18n.t('Enter SERPHouse API Key')}
|
||||||
|
bind:value={webConfig.SERPHOUSE_API_KEY}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mt-1.5">
|
||||||
|
<div class=" self-center text-xs font-medium mb-1">
|
||||||
|
{$i18n.t('SERPHouse Domain')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex w-full">
|
||||||
|
<div class="flex-1">
|
||||||
|
<input
|
||||||
|
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
|
||||||
|
type="text"
|
||||||
|
placeholder="google.com"
|
||||||
|
bind:value={webConfig.SERPHOUSE_DOMAIN}
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{:else if webConfig.WEB_SEARCH_ENGINE === 'serply'}
|
{:else if webConfig.WEB_SEARCH_ENGINE === 'serply'}
|
||||||
<div class="mb-2.5 flex w-full flex-col">
|
<div class="mb-2.5 flex w-full flex-col">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in new issue
Block a user