Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion docling/datamodel/settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
from contextlib import contextmanager
from pathlib import Path
from typing import Annotated, Optional, Tuple
from typing import Annotated, Iterator, Optional, Tuple

from pydantic import AfterValidator, BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict
Expand Down Expand Up @@ -70,5 +71,38 @@ class AppSettings(BaseSettings):
settings = AppSettings()


def defaults() -> AppSettings:
"""Return a fresh settings instance populated from the current environment."""
return AppSettings()


@contextmanager
def scoped(
*,
perf: BatchConcurrencySettings | None = None,
debug: DebugSettings | None = None,
inference: InferenceSettings | None = None,
) -> Iterator[AppSettings]:
"""Temporarily override selected settings and restore them on exit."""
saved = {
"perf": settings.perf.model_copy(deep=True),
"debug": settings.debug.model_copy(deep=True),
"inference": settings.inference.model_copy(deep=True),
}

try:
if perf is not None:
settings.perf = perf
if debug is not None:
settings.debug = debug
if inference is not None:
settings.inference = inference
yield settings
finally:
settings.perf = saved["perf"].model_copy(deep=True)
settings.debug = saved["debug"].model_copy(deep=True)
settings.inference = saved["inference"].model_copy(deep=True)


def default_compile_model() -> bool:
return settings.inference.compile_torch_models
31 changes: 31 additions & 0 deletions tests/test_settings_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,34 @@ def test_compile_model_defaults_from_settings(monkeypatch):
assert TransformersObjectDetectionEngineOptions().compile_model is True
assert TransformersImageClassificationEngineOptions().compile_model is True
assert TransformersVlmEngineOptions().compile_model is True


def test_scoped_settings_restores_state():
import importlib

import docling.datamodel.settings as settings_module

settings_module = importlib.reload(settings_module)

original = settings_module.settings.model_copy(deep=True)

with pytest.raises(RuntimeError):
with settings_module.scoped(
perf=settings_module.BatchConcurrencySettings(page_batch_size=99),
debug=settings_module.DebugSettings(profile_pipeline_timings=True),
inference=settings_module.InferenceSettings(compile_torch_models=False),
):
assert settings_module.settings.perf.page_batch_size == 99
assert settings_module.settings.debug.profile_pipeline_timings is True
assert settings_module.settings.inference.compile_torch_models is False
raise RuntimeError("boom")

assert settings_module.settings.model_dump(mode="json") == original.model_dump(
mode="json"
)

fresh = settings_module.defaults()
assert fresh is not settings_module.settings
assert fresh.model_dump(mode="json") == settings_module.settings.model_dump(
mode="json"
)