Skip to content

Commit 97107f6

Browse files
committed
refactor: remove save methods from settings
Config files should be created/edited manually and version controlled, not generated programmatically.
1 parent 43bd053 commit 97107f6

File tree

2 files changed

+6
-79
lines changed

2 files changed

+6
-79
lines changed

src/datajoint/settings.py

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -311,28 +311,6 @@ def get_store_spec(self, store: str) -> Dict[str, Any]:
311311

312312
return spec
313313

314-
def save(self, filename: Optional[Union[str, Path]] = None, verbose: bool = False) -> None:
315-
"""
316-
Save settings to a JSON file.
317-
318-
Args:
319-
filename: Path to save the configuration. Defaults to datajoint.json in cwd.
320-
verbose: If True, log the save operation.
321-
"""
322-
if filename is None:
323-
filename = Path.cwd() / CONFIG_FILENAME
324-
325-
data = self._to_flat_dict()
326-
# Remove secrets from saved config
327-
secrets_keys = ["database.password", "external.aws_secret_access_key"]
328-
for key in secrets_keys:
329-
data.pop(key, None)
330-
331-
with open(filename, "w") as f:
332-
json.dump(data, f, indent=4, default=str)
333-
if verbose:
334-
logger.info(f"Saved settings to {filename}")
335-
336314
def load(self, filename: Union[str, Path]) -> None:
337315
"""
338316
Load settings from a JSON file.
@@ -352,31 +330,6 @@ def load(self, filename: Union[str, Path]) -> None:
352330
self._update_from_flat_dict(data)
353331
self._config_path = filepath
354332

355-
def _to_flat_dict(self) -> Dict[str, Any]:
356-
"""Convert settings to flat dict with dot notation keys."""
357-
result: Dict[str, Any] = {}
358-
359-
def flatten(obj: Any, prefix: str = "") -> None:
360-
if isinstance(obj, BaseSettings):
361-
for name in obj.model_fields:
362-
if name.startswith("_"):
363-
continue
364-
value = getattr(obj, name)
365-
key = f"{prefix}.{name}" if prefix else name
366-
if isinstance(value, BaseSettings):
367-
flatten(value, key)
368-
elif isinstance(value, SecretStr):
369-
result[key] = value.get_secret_value() if value else None
370-
elif isinstance(value, Path):
371-
result[key] = str(value)
372-
else:
373-
result[key] = value
374-
elif isinstance(obj, dict):
375-
result[prefix] = obj
376-
377-
flatten(self)
378-
return result
379-
380333
def _update_from_flat_dict(self, data: Dict[str, Any]) -> None:
381334
"""Update settings from a flat dict with dot notation keys."""
382335
for key, value in data.items():

tests/test_settings.py

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Tests for DataJoint settings module."""
22

3-
import json
43
from pathlib import Path
54

65
import pytest
@@ -245,51 +244,26 @@ def test_override_restores_on_exception(self):
245244
assert dj.config.safemode == original
246245

247246

248-
class TestSaveLoad:
249-
"""Test saving and loading configuration."""
247+
class TestLoad:
248+
"""Test loading configuration."""
250249

251-
def test_save_and_load(self, tmp_path):
252-
"""Test saving and loading configuration."""
250+
def test_load_config_file(self, tmp_path):
251+
"""Test loading configuration from file."""
253252
filename = tmp_path / "test_config.json"
253+
filename.write_text('{"database": {"host": "loaded_host"}}')
254254
original_host = dj.config.database.host
255255

256256
try:
257-
dj.config.database.host = "saved_host"
258-
dj.config.save(filename)
259-
dj.config.database.host = "reset_host"
260257
dj.config.load(filename)
261-
262-
assert dj.config.database.host == "saved_host"
258+
assert dj.config.database.host == "loaded_host"
263259
finally:
264260
dj.config.database.host = original_host
265261

266-
def test_save_excludes_secrets(self, tmp_path):
267-
"""Test that save() excludes secret values."""
268-
filename = tmp_path / "test_config.json"
269-
original_password = dj.config.database.password
270-
271-
try:
272-
dj.config.database.password = "should_not_save"
273-
dj.config.save(filename)
274-
275-
with open(filename) as f:
276-
saved = json.load(f)
277-
278-
assert "database.password" not in saved
279-
finally:
280-
dj.config.database.password = original_password
281-
282262
def test_load_nonexistent_file(self):
283263
"""Test loading nonexistent file raises FileNotFoundError."""
284264
with pytest.raises(FileNotFoundError):
285265
dj.config.load("/nonexistent/path/config.json")
286266

287-
def test_save_default_filename(self, tmp_path, monkeypatch):
288-
"""Test save() uses datajoint.json in cwd by default."""
289-
monkeypatch.chdir(tmp_path)
290-
dj.config.save()
291-
assert (tmp_path / CONFIG_FILENAME).exists()
292-
293267

294268
class TestStoreSpec:
295269
"""Test external store configuration."""

0 commit comments

Comments
 (0)