-
Notifications
You must be signed in to change notification settings - Fork 2
features engine implementations
Active contributors: Magnus Hedemark
SlopSearX ships with 12 built-in engine adapters. Each adapter lives in its own file under engines/, is registered via the @register_engine decorator, and subclasses either EngineAdapter (for API-based engines) or ScrapeAdapter (for HTML-scrape engines). Adding a new engine requires zero changes to the orchestrator.
Every adapter follows the same common pattern. The search() method receives a query string and optional params dict, executes the search against the backend, and returns an AdapterResponse. Errors are never raised — they are classified in AdapterResponse.status using the EngineStatus enum (OK, RATE_LIMITED, BLOCKED, ERROR, TIMEOUT). Rate limits are enforced through a shared Valkey-backed rate limiter injected at startup.
| Engine | File | Type | Categories | Auth | Notable behaviors |
|---|---|---|---|---|---|
| Brave | engines/brave.py |
api | general, news, science, images | API key (ENGINE_BRAVE_API_KEY) |
Rich JSON response with thumbnails; requires X-Subscription-Token header |
| Wikipedia | engines/wikipedia.py |
api | general, science, reference | None | Two-stage pipeline: opensearch for titles, then rich_query for extracts + pageimages |
| DuckDuckGo | engines/duckduckgo.py |
scrape | general, news | None | HTML form POST; _is_challenge_page() detection; CSS selector .result parsing |
engines/google.py |
scrape | general, news | None | GET request; challenge detection; div.g CSS selector parsing |
|
| GitHub | engines/github.py |
api | general, reference, github:code, github:issues, github:prs | Token (ENGINE_GITHUB_TOKEN) |
Three sub-modes (code, issues/issues, repositories) based on category routing |
| HuggingFace | engines/huggingface.py |
api | general, science, huggingface:datasets, huggingface:papers | Optional token | Three sub-modes (models, datasets, papers) based on category routing |
| Internet Archive | engines/internetarchive.py |
api | reference, web:archive, historical | None | Domain queries route to Wayback CDX API; general queries use advancedsearch |
| OpenAlex | engines/openalex.py |
api | general, science, reference | None | Scholarly works search; inverted index abstract reconstruction via _reconstruct_abstract()
|
| Stack Exchange | engines/stackexchange.py |
api | general, reference, science, stackexchange:code, stackexchange:serverfault | Optional API key | Category-based site routing (stackoverflow, serverfault) |
| arXiv | engines/arxiv.py |
api | general, science, reference | None | Atom XML feed parsing via xml.etree.ElementTree; rate-limited to 1 req/3s per arXiv ToS |
| Hacker News | engines/hackernews.py |
api | general, news | None | Algolia API integration; filters to stories only via tags: "story", excludes comments |
| Semantic Scholar | engines/semanticscholar.py |
api | general, science, reference | Optional API key | Paper search with citation data, author metadata, arXiv cross-referencing via externalIds |
The adapter class hierarchy has two levels:
classDiagram
class EngineAdapter {
+name: str
+display_name: str
+env_prefix: str
+engine_type: str
+categories: list[str]
+search(query, params)* AdapterResponse
+health() EngineStatus
+warmup() None
+shutdown() None
}
class ScrapeAdapter {
+engine_type: str
+request_headers: dict
+timeout_ms: int
+health() EngineStatus
}
class BraveAdapter
class WikipediaAdapter
class GitHubAdapter
class HuggingFaceAdapter
class InternetArchiveAdapter
class OpenAlexAdapter
class StackExchangeAdapter
class ArxivAdapter
class HackerNewsAdapter
class SemanticScholarAdapter
class DuckDuckGoAdapter
class GoogleAdapter
EngineAdapter <|-- ScrapeAdapter
EngineAdapter <|-- BraveAdapter
EngineAdapter <|-- WikipediaAdapter
EngineAdapter <|-- GitHubAdapter
EngineAdapter <|-- HuggingFaceAdapter
EngineAdapter <|-- InternetArchiveAdapter
EngineAdapter <|-- OpenAlexAdapter
EngineAdapter <|-- StackExchangeAdapter
EngineAdapter <|-- ArxivAdapter
EngineAdapter <|-- HackerNewsAdapter
EngineAdapter <|-- SemanticScholarAdapter
ScrapeAdapter <|-- DuckDuckGoAdapter
ScrapeAdapter <|-- GoogleAdapter
-
search() flow — read config (base_url, timeout, api_key), build request parameters, send HTTP request via httpx, measure latency, parse response into
SearchResultlist, returnAdapterResponse. -
Error handling — every adapter catches
httpx.TimeoutException, HTTP status errors (429 for rate limiting, 403/503 for blocking), and generic exceptions. All are classified intoEngineStatusand returned inAdapterResponse. -
Rate limiting integration — the rate limiter is injected into each adapter at construction time. Adapters call
self.rate_limiter.acquire()before making requests. The rate limiter is Valkey-backed and distributed across all replicas.
-
BraveAdapter — requires an API key set via
ENGINE_BRAVE_API_KEY. UsesX-Subscription-Tokenheader for authentication. Parsesweb.resultsfrom the JSON response, extracting thumbnails from the nestedthumbnail.srcfield. -
WikipediaAdapter — two-stage pipeline. Stage 1 calls the
opensearchAPI action to resolve the query to page titles. Stage 2 calls thequeryAPI action withprop=extracts|pageimagesto fetch rich content (summaries, thumbnails) for each resolved title. -
DuckDuckGoAdapter — a
ScrapeAdaptersubclass. Sends an HTML form POST tohttps://html.duckduckgo.com/html/. The_is_challenge_page()method detects CAPTCHA walls by checking for known indicators in the response body. Parses results using CSS selector.resultwith lxml. -
GoogleAdapter — a
ScrapeAdaptersubclass. Sends a GET request tohttps://www.google.com/searchwith stealth headers. Challenge detection checks for reCAPTCHA and "unusual traffic" indicators. Parses organic results using thediv.gCSS selector. -
GitHubAdapter — selects its API endpoint based on category routing:
github:coderoutes to/search/code,github:issuesorgithub:prsroutes to/search/issues, and everything else routes to/search/repositories. RequiresENGINE_GITHUB_TOKEN. Returns HTTP 422 for code searches without sufficient qualifiers, handled gracefully as empty results. -
HuggingFaceAdapter — routes to one of three HuggingFace API endpoints based on category:
huggingface:datasetsroutes to/api/datasets,huggingface:papersroutes to/api/papers, and the default routes to/api/models. Parses model metadata (pipeline_tag, library_name, downloads, likes) into rich result content. -
InternetArchiveAdapter — detects whether the query looks like a domain name (e.g.,
example.com) and routes domain queries to the Wayback CDX API for snapshot data. General queries use theadvancedsearch.phpendpoint for books, audio, video, and other archived media. -
OpenAlexAdapter — searches scholarly works via
https://api.openalex.org/works. Reconstructs abstracts from OpenAlex's inverted index format ({"word": [positions], ...}) using the_reconstruct_abstract()helper. Sorts results bycited_by_count:desc. -
StackExchangeAdapter — maps sub-categories to Stack Exchange sites:
stackexchange:coderoutes to stackoverflow,stackexchange:serverfaultroutes to serverfault, and the default is stackoverflow. Converts Unix timestamps to ISO 8601 for thepublished_datefield. -
arXivAdapter — parses Atom XML feeds using
xml.etree.ElementTreewith namespacehttp://www.w3.org/2005/Atom. Rate-limited to 1 request per 3 seconds as required by arXiv's Terms of Service. Strips arXiv IDs from the atom<id>element and constructs paper URLs. -
HackerNewsAdapter — integrates with Algolia's HN search API at
https://hn.algolia.com/api/v1/search. Filters to stories only by passingtags: "story", deliberately excluding comments. - SemanticScholarAdapter — searches papers via the Semantic Scholar graph API. Requests rich fields (title, url, abstract, citationCount, publicationDate, externalIds, authors). Builds content from abstract, author names (truncated to 3 with "et al."), citation count, and arXiv cross-reference.
- All files in
engines/directory -
slopsearx/adapter.py— base classesEngineAdapterandScrapeAdapter -
slopsearx/ratelimit.py— distributed rate limiting shared by all engines
- Output formatters — how engine results are serialized
-
Search result types — the
SearchResultdataclass - System architecture — request flow through engines
- Glossary — project-specific terms