-
Notifications
You must be signed in to change notification settings - Fork 2
systems configuration
Active contributors: Magnus Hedemark
Three-layer configuration model: built-in defaults, optional YAML config file, environment variable overrides. Env vars always win.
| Type | File | Description |
|---|---|---|
Config |
slopsearx/config.py |
Top-level configuration dataclass. Contains engines (dict of EngineEntry), cache (CacheConfig), ranking (RankingConfig), routing (RoutingConfig), default_engines, enable_suggestions, and log_level. |
CacheConfig |
slopsearx/config.py |
Cache subsystem configuration: ttl_seconds (default 300), max_result_sets (default 10000), revalidate_on_hit (default False). |
RankingConfig |
slopsearx/config.py |
Ranking strategy selector: strategy (default "presence", with "weighted_fusion" and "learning_to_rank" as future options). |
RoutingConfig |
slopsearx/config.py |
Query routing configuration: enabled (default True), topics (dict of topic signatures), fallback (list of fallback engines). |
EngineEntry |
slopsearx/config.py |
Per-engine configuration dataclass. Covers enabled, base_url, type, timeout_ms, max_results, rate_limit, weight, api_key, category overrides (categories, categories_add, categories_remove), and scrape-specific proxy fields (proxy_pool, scrape_proxy_url). |
load_config |
slopsearx/config.py |
Public function that loads and layers all config sources. Returns a fully resolved Config dataclass. |
_load_env_overrides |
slopsearx/config.py |
Reads all ENGINE_* and SEARCH_* environment variables and returns a flat dict of overrides. |
_DEFAULT_ENGINES |
slopsearx/config.py |
Hardcoded default config dicts for all 24 engines, including base URLs, timeouts, rate limits, result caps, and weight values. |
Configuration is loaded in three layers. Each layer overrides the previous one:
1. Built-in defaults (hardcoded in _DEFAULT_ENGINES)
2. YAML config file (optional, at /etc/slopsearx/config.yaml by default)
3. Env var overrides (ENGINE_* and SEARCH_* vars always win)
load_config() executes these steps in order:
-
Start with built-in defaults. Creates a
Configobject withEngineEntryinstances populated from_DEFAULT_ENGINES, a defaultCacheConfig, and a defaultRankingConfig. -
Layer the config file. If a YAML file exists at the specified path, it is loaded with
yaml.safe_load(). Engine configs from the file are merged over defaults: existing engines get their fields overridden on a per-key basis, and new engines are added. Cache and ranking configs are also overridden from the file. -
Layer environment variables.
_load_env_overrides()scans all environment variables starting withENGINE_orSEARCH_and builds a flat override dict. These overrides are applied to the resolvedConfigobject with_apply_env_overrides().
Env vars use two namespaces:
-
ENGINE_<NAME>_<SETTING>for per-engine settings. Example:ENGINE_BRAVE_API_KEY,ENGINE_DUCKDUCKGO_CATEGORIES_ADD -
SEARCH_<SETTING>for global settings. Example:SEARCH_CACHE_TTL_SECONDS,SEARCH_LOG_LEVEL,SEARCH_DEFAULT_ENGINES
The _load_env_overrides() function parses these into a flat dict with dotted keys:
ENGINE_BRAVE_API_KEY → engines.brave.api_key
ENGINE_DUCKDUCKGO_ENABLED → engines.duckduckgo.enabled
SEARCH_CACHE_TTL_SECONDS → search_cache_ttl_seconds
The config file is optional YAML at /etc/slopsearx/config.yaml:
engines:
brave:
enabled: true
timeout_ms: 5000
max_results: 10
duckduckgo:
enabled: true
timeout_ms: 10000
max_results: 10
proxy_pool: "residential"
cache:
ttl_seconds: 300
max_result_sets: 10000
ranking:
strategy: "presence"
routing:
enabled: true
topics:
code:
keywords: [python, javascript, rust, golang, react]
engines: [brave, github, stackexchange, wikipedia]
science:
keywords: [quantum, physics, biology, paper, doi]
engines: [brave, arxiv, semanticscholar, openalex, wikipedia]
fallback: [brave, wikipedia]
default_engines:
- brave
- wikipedia
- duckduckgo
log_level: "INFO"
enable_suggestions: trueAt 50+ replicas with 10+ engines, env-var-only configuration has two hard limits:
- Kubernetes pod spec limit of ~32768 bytes for all environment variables combined. Ten engines with ten config params each using namespace-prefixed names easily exceeds this.
- Operational friction. Changing an engine's timeout or rate limit requires a full rollout with env-var-only. A mounted ConfigMap can be hot-reloaded by the application.
The hybrid model preserves the core stateless property: the file is read once at startup and never written to by the application. Replicas remain interchangeable.
The EngineEntry dataclass supports three category override mechanisms:
-
categories: a list that fully replaces the engine's self-declared categories -
categories_add: a list appended to the engine's self-declared categories -
categories_remove: a list suppressed from the engine's self-declared categories
These can be set via config file or env vars. When set via env vars, the values are comma-separated strings that get coerced to lists.
Scrape-based engines (DuckDuckGo, Google) support two proxy configuration options on EngineEntry:
-
proxy_pool: Name or list of proxy URLs for round-robin rotation. Typically set to a static pool or a service name. -
scrape_proxy_url: A dynamic proxy endpoint URL. When set, the proxy pool uses this single endpoint instead of local rotation.
These are consumed by ProxyPool which integrates with ScrapeAdapter at construction time.
-
Server startup:
startup()inserver.pycallsload_config(), then convertsEngineEntrydataclasses to dicts fordiscover_engines(). The config also drivesQueryRouterinitialization,SuggestionServiceopt-in (enable_suggestions), andEngineStatsTrackersetup. -
Per-engine config: Each engine's adapter instance receives its config dict as
self.config -
Cache config:
SearchCacheTTL values are derived from the loaded config -
Routing config:
QueryRouterreads theroutingsection from config to build topic-signature mappings for query-based engine selection -
Suggestion opt-in: The
enable_suggestionsflag controls whetherSuggestionService(Brave Suggest API) is initialized at startup - Env var injection: API keys are read from env vars at config loading time, never stored in the config file
- Adding a new config parameter: add a field to the relevant dataclass (
Config,EngineEntry,CacheConfig,RankingConfig) - Adding a new engine default: add an entry to
_DEFAULT_ENGINES - Changing env var parsing: modify
_load_env_overrides()or_apply_env_overrides()
| File | Description |
|---|---|
slopsearx/config.py |
All config loading logic, dataclasses, env var parsing, and engine defaults |