Config Files¶
Manipulate TOML, YAML, JSON, and INI files with the same target-based API.
TOML Files¶
Common for pyproject.toml:
toml = rj.toml("pyproject.toml")
# Read values (dotted key path)
version = toml.get("project.version")
line_length = toml.get("tool.black.line-length", default=88)
# Set values
toml.set("project.version", "2.0.0")
toml.set("tool.black.line-length", 110)
toml.set("tool.ruff.select", ["E", "F", "W"])
# Delete keys
toml.delete("tool.deprecated-tool")
# Get entire sections
black_config = toml.get_section("tool.black")
# Replace entire file content (validates TOML syntax)
toml.rewrite(new_content)
Common pyproject.toml Operations¶
toml = rj.toml("pyproject.toml")
# Update version
toml.set("project.version", "1.2.0")
# Add a dependency
deps = toml.get("project.dependencies", default=[])
deps.append("requests>=2.28.0")
toml.set("project.dependencies", deps)
# Configure tools
toml.set("tool.black.line-length", 110)
toml.set("tool.black.target-version", ["py310", "py311"])
toml.set("tool.ruff.select", ["E", "F", "W", "I"])
toml.set("tool.mypy.strict", True)
YAML Files¶
yaml = rj.yaml("config.yml")
# Read values
debug = yaml.get("app.debug", default=False)
hosts = yaml.get("database.hosts")
# Set values
yaml.set("app.version", "2.0.0")
yaml.set("database.pool_size", 10)
# Delete keys
yaml.delete("deprecated_setting")
YAML editing uses ruamel.yaml in round-trip mode,
so untouched parts of the file keep their original formatting — comments, quote
styles, key order, and scalar wrapping are all preserved. Only the keys you
change are rewritten, keeping diffs minimal. Install the dependency with
pip install rejig[yaml].
Nested Structures¶
yaml = rj.yaml("docker-compose.yml")
# Access nested values
image = yaml.get("services.web.image")
ports = yaml.get("services.web.ports")
# Set nested values
yaml.set("services.web.environment.DEBUG", "false")
JSON Files¶
json_file = rj.json("package.json")
# Read values
name = json_file.get("name")
version = json_file.get("version")
scripts = json_file.get("scripts", default={})
# Set values
json_file.set("version", "2.0.0")
json_file.set("scripts.test", "pytest")
# Delete keys
json_file.delete("devDependencies.old-package")
Key Paths¶
get(), set() and delete() on TOML, YAML and JSON targets accept the key
path in three forms:
# 1. Dotted string (the common case)
toml.get("tool.black.line-length")
# 2. List of literal segments
toml.get(["tool", "black", "line-length"])
# 3. KeyPath — a pathlib-style builder (from rejig import KeyPath)
from rejig import KeyPath
toml.get(KeyPath("tool") / "black" / "line-length")
The dotted string splits on every ., so it cannot address a key that
contains a literal dot. Use a list or KeyPath (each segment is literal) for
those:
# A single key named "CVE-2026.0001" — the dotted string would split it
yaml.set(KeyPath("security") / "ignore" / "CVE-2026.0001", "reviewed")
yaml.get(["security", "ignore", "CVE-2026.0001"])
A pathlib.PurePath is accepted too, and a KeyPath is a sequence of its
segments (it can be indexed, iterated and measured with len()).
INI Files¶
ini = rj.ini("setup.cfg")
# Read values (section, key)
name = ini.get("metadata", "name")
version = ini.get("metadata", "version")
# Set values
ini.set("metadata", "version", "2.0.0")
ini.set("options", "python_requires", ">=3.10")
# Delete keys
ini.delete_key("options", "deprecated_option")
# Add sections
ini.add_section("tool:pytest")
ini.set("tool:pytest", "testpaths", "tests")
# Get entire file as nested dict
data = ini.get_data()
Text Files¶
For files without structured format:
text = rj.text_file("README.md")
# Read content
result = text.get_content()
if result:
print(result.data)
# Line operations
text.get_line(1) # First line content (str | None)
# Pattern operations
matches = text.find_lines(r"## .*") # List of (line_number, line) tuples
text.replace(r"v\d+\.\d+\.\d+", "v2.0.0") # Update version strings
Checking Existence¶
toml = rj.toml("pyproject.toml")
if toml.exists():
version = toml.get("project.version")
else:
print("pyproject.toml not found")
Result Handling¶
Config operations return Result:
result = toml.set("project.version", "2.0.0")
if result:
print(f"Updated {result.files_changed}")
else:
print(f"Failed: {result.message}")
Common Patterns¶
Update Version Everywhere¶
new_version = "2.0.0"
# pyproject.toml
rj.toml("pyproject.toml").set("project.version", new_version)
# package.json (if exists)
pkg = rj.json("package.json")
if pkg.exists():
pkg.set("version", new_version)
# __init__.py
init = rj.file("src/mypackage/__init__.py")
init.replace_pattern(r'__version__ = "[^"]+"', f'__version__ = "{new_version}"')
Sync Tool Configuration¶
# Ensure consistent settings across projects
toml = rj.toml("pyproject.toml")
toml.set("tool.black.line-length", 110)
toml.set("tool.isort.profile", "black")
toml.set("tool.isort.line_length", 110)
toml.set("tool.mypy.python_version", "3.10")
toml.set("tool.mypy.strict", True)
Add GitHub Actions Workflow¶
yaml = rj.yaml(".github/workflows/test.yml")
yaml.set("name", "Tests")
yaml.set("on.push.branches", ["main"])
yaml.set("on.pull_request.branches", ["main"])
yaml.set("jobs.test.runs-on", "ubuntu-latest")
yaml.set("jobs.test.steps", [
{"uses": "actions/checkout@v4"},
{"uses": "actions/setup-python@v5", "with": {"python-version": "3.10"}},
{"run": "pip install -e .[dev]"},
{"run": "pytest"},
])
Next Steps¶
- Error Handling — Handle failures gracefully
- Examples — Real-world patterns