Files
hey-search/backend/app/engines/base.py
T
2026-02-23 14:37:07 +11:00

59 lines
1.6 KiB
Python

"""Abstract base class for search engines."""
from __future__ import annotations
import abc
import logging
from typing import Literal
import httpx
from app.models import WebResult, ImageResult
logger = logging.getLogger(__name__)
SearchCategory = Literal["web", "images"]
# Shared async HTTP client
_client: httpx.AsyncClient | None = None
def get_http_client() -> httpx.AsyncClient:
global _client
if _client is None or _client.is_closed:
_client = httpx.AsyncClient(
timeout=httpx.Timeout(10.0, connect=5.0),
follow_redirects=True,
headers={
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
},
)
return _client
class SearchEngine(abc.ABC):
"""Abstract search engine interface."""
name: str
display_name: str
supports_web: bool = True
supports_images: bool = True
@abc.abstractmethod
async def search_web(self, query: str, page: int = 1) -> list[WebResult]:
"""Perform a web search and return results."""
@abc.abstractmethod
async def search_images(self, query: str, page: int = 1) -> list[ImageResult]:
"""Perform an image search and return results."""
async def autocomplete(self, query: str) -> list[str]:
"""Return autocomplete suggestions. Override if supported."""
return []