Problem
OmopGraphConfig.get_config() (and OmopEmbConfig.get_config(), see associated issue) are called deep inside pure functions and dataclass field defaults rather than at system boundaries. This couples algorithmic code to the file-based config system, makes unit testing require a real config file, and hides I/O inside what appears to be a data construction or arithmetic call.
Specific locations:
src/omop_graph/reasoning/grounding.py:78
max_depth: int = field(
default_factory=lambda: OmopGraphConfig.get_config().max_depth
)
A frozen dataclass reads config on every instantiation where max_depth is not supplied. Any test that constructs GroundingConstraints without max_depth (e.g. via annotate_text) fails without a config file.
src/omop_graph/graph/paths.py:259, 472, 784
cfg = OmopGraphConfig.get_config()
if max_depth is None:
max_depth = cfg.max_depth
Config is read inline inside graph-traversal functions when optional parameters are absent. A caller that passes explicit values never touches config; one that omits them triggers a file read buried inside an algorithmic function.
src/omop_graph/graph/kg.py:194
cfg = OmopEmbConfig.get_config()
Config from a sibling package is read during KG initialisation, coupling KG construction to omop-emb's config file presence.
Root cause
Config reads are scattered across the call stack rather than consolidated at entry points (CLI commands, service constructors, or test fixtures). Pure functions and data classes should receive explicit values; only boundary code (CLI, factory functions, integration test setup) should call get_config().
Proposed direction
- Change
GroundingConstraints.max_depth to default=6 (the same literal as the Pydantic field default in OmopGraphConfig). Callers that want to honour user config read it explicitly and pass it in.
- Remove inline
get_config() calls from paths.py functions. Callers that omit max_depth/max_paths and want config-driven defaults should resolve them before calling; alternatively, expose a thin wrapper at the service layer that does the config read once.
- Remove the
OmopEmbConfig.get_config() call from kg.py. Pass the required config values as constructor parameters so the KG remains independent of the omop-emb config file.
Problem
OmopGraphConfig.get_config()(andOmopEmbConfig.get_config(), see associated issue) are called deep inside pure functions and dataclass field defaults rather than at system boundaries. This couples algorithmic code to the file-based config system, makes unit testing require a real config file, and hides I/O inside what appears to be a data construction or arithmetic call.Specific locations:
src/omop_graph/reasoning/grounding.py:78A frozen dataclass reads config on every instantiation where
max_depthis not supplied. Any test that constructsGroundingConstraintswithoutmax_depth(e.g. viaannotate_text) fails without a config file.src/omop_graph/graph/paths.py:259,472,784Config is read inline inside graph-traversal functions when optional parameters are absent. A caller that passes explicit values never touches config; one that omits them triggers a file read buried inside an algorithmic function.
src/omop_graph/graph/kg.py:194Config from a sibling package is read during KG initialisation, coupling KG construction to
omop-emb's config file presence.Root cause
Config reads are scattered across the call stack rather than consolidated at entry points (CLI commands, service constructors, or test fixtures). Pure functions and data classes should receive explicit values; only boundary code (CLI, factory functions, integration test setup) should call
get_config().Proposed direction
GroundingConstraints.max_depthtodefault=6(the same literal as the Pydantic field default inOmopGraphConfig). Callers that want to honour user config read it explicitly and pass it in.get_config()calls frompaths.pyfunctions. Callers that omitmax_depth/max_pathsand want config-driven defaults should resolve them before calling; alternatively, expose a thin wrapper at the service layer that does the config read once.OmopEmbConfig.get_config()call fromkg.py. Pass the required config values as constructor parameters so the KG remains independent of the omop-emb config file.