Skip to content

feat: support {env:VAR} interpolation in settings - #241

Open
gaojunran wants to merge 1 commit into
cocoindex-io:mainfrom
gaojunran:feat/env-interpolation
Open

feat: support {env:VAR} interpolation in settings#241
gaojunran wants to merge 1 commit into
cocoindex-io:mainfrom
gaojunran:feat/env-interpolation

Conversation

@gaojunran

Copy link
Copy Markdown

Summary

Allow any string value in global_settings.yml and project settings.yml to reference environment variables via {env:VAR_NAME} placeholders, expanded at load time.

Motivation

Currently, envs values and all other config fields are treated as literal strings. The only way to keep secrets out of config files is shell environment inheritance. This works for envs (which are injected into os.environ), but not for other fields like embedding.model or OPENAI_BASE_URL when you want to compose a value from an env var without putting the full literal in the file.

This PR adds a simple {env:VAR_NAME} interpolation syntax that works on every string value in both global and project settings.

Usage

embedding:
  model: openai/your-model-name
envs:
  OPENAI_BASE_URL: "https://{env:MY_LLM_HOST}/v1"
  OPENAI_API_KEY: "{env:MY_OPENAI_API_KEY}"
  • Placeholders can appear anywhere in a string (partial interpolation supported)
  • Works on every config field (model name, API keys, base URLs, patterns, etc.)
  • Unset variables are replaced with an empty string (no error)
  • Applies to both global_settings.yml and project-level settings.yml

Implementation

A single recursive function _expand_env_placeholders() in settings.py walks the parsed YAML dict/list/str tree and replaces {env:VAR} in strings via regex. It is called in load_user_settings() and load_project_settings() right after yaml.safe_load() and before dataclass construction — one line change at each call site, keeping the logic centralized.

Changes

  • src/cocoindex_code/settings.py: add _expand_env_placeholders(), call it in both load_user_settings and load_project_settings
  • tests/test_settings.py: 6 new test cases covering envs interpolation, partial strings, model name interpolation, unset var behavior, save/load round-trip, and project settings interpolation
  • README.md: document the feature with examples

Test plan

  • All 6 new test cases pass (verified via standalone script, since full test suite requires cocoindex runtime dependency not available in this environment)
  • uv run pytest tests/test_settings.py passes in a full dev environment
  • uv run ruff check . and uv run mypy . pass

Allow any string value in global_settings.yml and project settings.yml
to reference environment variables via {env:VAR_NAME} placeholders.
Placeholders are expanded at load time, before dataclass construction,
so every config field (model name, API keys, base URLs, patterns, etc.)
can use them. Unset variables are replaced with empty strings.

This lets users keep secrets out of config files without relying solely
on shell environment inheritance.
@badmonster0
badmonster0 requested a review from georgeh0 July 30, 2026 05:20
@badmonster0

Copy link
Copy Markdown
Member

thanks a lot @gaojunran for the PR! @georgeh0 wdyt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants