Skip to content

Configuration

Typed settings loaded from YAML and .env. The models and loaders are importable from sci_etl_core.

sci_etl_core.config

T module-attribute

T = TypeVar('T', bound='BaseAppConfig')

LLMConfig

Bases: BaseModel

Chat-completion endpoint settings.

:meth:~sci_etl_core.llm.openai_compatible_async.AsyncOpenAICompatibleClient.from_config builds a client from them. api_key is a :class:~pydantic.SecretStr, so it never appears in a repr or a log line. :func:load_config takes it from the environment variable it names, and falls back to the YAML value when that is unset. timeout is in seconds.

api_key class-attribute instance-attribute

api_key: SecretStr = SecretStr('')

base_url class-attribute instance-attribute

base_url: str = 'https://api.openai.com/v1'

model class-attribute instance-attribute

model: str = 'gpt-4o-mini'

timeout class-attribute instance-attribute

timeout: int = Field(default=120, gt=0)

HttpConfig

Bases: BaseModel

HTTP settings for the clients and extractors that call a remote source.

user_agent defaults to sci-etl-core/<installed version>.

user_agent class-attribute instance-attribute

user_agent: str = DEFAULT_USER_AGENT

max_retries class-attribute instance-attribute

max_retries: int = Field(default=3, ge=1)

backoff_factor class-attribute instance-attribute

backoff_factor: float = Field(default=2.0, ge=0)

timeout class-attribute instance-attribute

timeout: int = Field(default=25, gt=0)

build_client

build_client() -> AsyncClient

Build an httpx.AsyncClient with this timeout and user_agent.

max_retries and backoff_factor are applied by the extractor, as :meth:~sci_etl_core.extractors.arxiv_async.AsyncArxivExtractor.from_config does, not by the client. Needs the async extra.

RateLimitConfig

Bases: BaseModel

A concurrency cap, or a token bucket when max_rate is set.

max_concurrency class-attribute instance-attribute

max_concurrency: int = Field(default=4, ge=1)

max_rate class-attribute instance-attribute

max_rate: float | None = Field(default=None, gt=0)

time_period class-attribute instance-attribute

time_period: float = Field(default=1.0, gt=0)

build_limiter

build_limiter() -> AsyncRateLimiter

Build the limiter these settings describe, as :func:~sci_etl_core.rate_limiter.build_rate_limiter does.

PipelineConfig

Bases: BaseModel

Settings for :class:~sci_etl_core.pipeline_async.AsyncETLPipeline and its runs.

max_concurrency configures the pipeline (see from_config), and :meth:run_arguments returns the arguments for run(). search_delay is the arXiv extractor's pause before each listing request.

.. deprecated:: 0.4.0 The keys max_records and max_workers are read as total_limit and max_concurrency, with a :class:DeprecationWarning. They will stop being accepted in 0.5.0.

search_query class-attribute instance-attribute

search_query: str = ''

total_limit class-attribute instance-attribute

total_limit: int = Field(default=100, ge=0)

page_size class-attribute instance-attribute

page_size: int = Field(default=100, ge=1)

search_delay class-attribute instance-attribute

search_delay: float = Field(default=3.0, ge=0)

sleep_between class-attribute instance-attribute

sleep_between: float = Field(default=5.0, ge=0)

max_concurrency class-attribute instance-attribute

max_concurrency: int = Field(default=6, ge=1)

newest_first class-attribute instance-attribute

newest_first: bool = False

max_records property

max_records: int

Deprecated alias of :attr:total_limit.

max_workers property

max_workers: int

Deprecated alias of :attr:max_concurrency.

run_arguments

run_arguments() -> dict[str, Any]

Return the keyword arguments for run() these settings describe.

Unpack them into the call, adding start_index when needed: await pipeline.run(**config.pipeline.run_arguments()).

BM25WeightsConfig

Bases: BaseModel

Per-field BM25 weights, as :class:~sci_etl_core.search.store_base.BM25Weights.

title class-attribute instance-attribute

title: float = Field(
    default=10.0, ge=0, allow_inf_nan=False
)

abstract class-attribute instance-attribute

abstract: float = Field(
    default=4.0, ge=0, allow_inf_nan=False
)

body class-attribute instance-attribute

body: float = Field(default=1.0, ge=0, allow_inf_nan=False)

to_weights

to_weights() -> BM25Weights

Build the BM25 weights.

FusionConfig

Bases: BaseModel

Rank fusion settings, as :class:~sci_etl_core.search.fusion.FusionParams.

k class-attribute instance-attribute

k: int = Field(default=60, ge=1)

weights class-attribute instance-attribute

weights: list[float] | None = None

to_params

to_params() -> FusionParams

Build the fusion parameters.

Raises:

Type Description
ValueError

A weight is negative or not finite.

HybridConfig

Bases: BaseModel

Candidate pool sizes, as :class:~sci_etl_core.search.hybrid_async.HybridParams.

candidate_pool class-attribute instance-attribute

candidate_pool: int = Field(default=100, ge=1)

chunk_pool_factor class-attribute instance-attribute

chunk_pool_factor: int = Field(default=5, ge=1)

to_params

to_params() -> HybridParams

Build the hybrid search parameters.

GraphConfig

Bases: BaseModel

Discovery graph bounds, as :class:~sci_etl_core.search.graph.GraphParams.

depth class-attribute instance-attribute

depth: int = Field(default=2, ge=0)

fanout class-attribute instance-attribute

fanout: int = Field(default=8, ge=1)

min_weight class-attribute instance-attribute

min_weight: float = Field(default=0.35, allow_inf_nan=False)

max_nodes class-attribute instance-attribute

max_nodes: int = Field(default=200, ge=1)

mutual_only class-attribute instance-attribute

mutual_only: bool = True

max_iterations class-attribute instance-attribute

max_iterations: int = Field(default=20, ge=1)

to_params

to_params() -> GraphParams

Build the discovery graph parameters.

SearchConfig

Bases: BaseModel

Settings for local search and discovery graphs.

bm25 class-attribute instance-attribute

bm25: BM25WeightsConfig = Field(
    default_factory=BM25WeightsConfig
)

fusion class-attribute instance-attribute

fusion: FusionConfig = Field(default_factory=FusionConfig)

hybrid class-attribute instance-attribute

hybrid: HybridConfig = Field(default_factory=HybridConfig)

graph class-attribute instance-attribute

graph: GraphConfig = Field(default_factory=GraphConfig)

BaseAppConfig

Bases: BaseModel

Root of an application config: the library's sections, plus any keys a subclass adds.

Unknown top-level keys are kept rather than rejected, so an application can read its own sections from the same YAML file. Subclass it to type those sections, and set extra="forbid" in the subclass to reject typos.

model_config class-attribute instance-attribute

model_config = ConfigDict(extra='allow')

llm class-attribute instance-attribute

llm: LLMConfig = Field(default_factory=LLMConfig)

http class-attribute instance-attribute

http: HttpConfig = Field(default_factory=HttpConfig)

full_text class-attribute instance-attribute

full_text: RateLimitConfig = Field(
    default_factory=RateLimitConfig
)

pipeline class-attribute instance-attribute

pipeline: PipelineConfig = Field(
    default_factory=PipelineConfig
)

search class-attribute instance-attribute

search: SearchConfig = Field(default_factory=SearchConfig)

load_yaml

load_yaml(path: Path) -> dict[str, Any]

Read a YAML config file.

Raises:

Type Description
ConfigurationError

The file is missing, is not valid YAML, or does not hold a mapping at the top level.

parse_yaml

parse_yaml(text: str, source: Path) -> dict[str, Any]

Parse YAML text that must hold a mapping; an empty document is {}.

Raises:

Type Description
ConfigurationError

The text is not valid YAML or its top level is not a mapping.

apply_api_key

apply_api_key(
    raw: dict[str, Any], api_key_env_var: str
) -> dict[str, Any]

Resolve the LLM API key, letting the environment override the YAML file.

A key supplied at runtime through api_key_env_var always wins, so a stale or leaked key written into a config file can never silently replace it. The YAML value is only a fallback for when the variable is unset or empty. A non-mapping llm section is left for validation to reject.

load_config

load_config(
    config_cls: type[T],
    yaml_path: Path,
    env_path: Path | None = None,
    api_key_env_var: str = "LLM_API_KEY",
) -> T

Load and validate a config from YAML plus a .env file.

Without env_path, .env is looked up from the current working directory upward, so the caller's project is searched rather than the location the library is installed in.

Raises:

Type Description
ConfigurationError

The YAML file is missing or unreadable, or the configuration fails validation.

validate_config

validate_config(
    config_cls: type[T], raw: dict[str, Any], source: Path
) -> T

Validate settings read from source against config_cls.

Raises:

Type Description
ConfigurationError

Validation failed. The message names each failing key and the reason but never the value that was read, so a secret such as an API key taken from the environment cannot reach a log or a terminal. The validation error is not chained for the same reason.

sci_etl_core.config_async

T module-attribute

T = TypeVar('T', bound=BaseAppConfig)

load_yaml_async async

load_yaml_async(path: Path) -> dict[str, Any]

Read a YAML config file without blocking the event loop.

Raises:

Type Description
ConfigurationError

The file is missing, is not valid YAML, or does not hold a mapping at the top level.

load_config_async async

load_config_async(
    config_cls: type[T],
    yaml_path: Path,
    env_path: Path | None = None,
    api_key_env_var: str = "LLM_API_KEY",
) -> T

Async counterpart of :func:sci_etl_core.config.load_config, with the same lookup rules.