Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e5d6932
recursively convert parsed dicts to typed dataclasses in loader
MikeGoldsmith Jun 3, 2026
582c37f
rename changelog fragment to PR #5269
MikeGoldsmith Jun 3, 2026
b302f93
tighten typing on conversion module
MikeGoldsmith Jun 3, 2026
3a6fd21
isolate typing.get_type_hints call to placate astroid 3.x on py3.14
MikeGoldsmith Jun 3, 2026
131378c
inline the typing.get_type_hints wrap
MikeGoldsmith Jun 3, 2026
3720621
add configure_sdk orchestrator for declarative config
MikeGoldsmith Jun 3, 2026
fd6c20a
rename changelog fragment to PR #5270
MikeGoldsmith Jun 3, 2026
7066419
honor OTEL_CONFIG_FILE in the SDK configurator
MikeGoldsmith Jun 3, 2026
da80d63
rename changelog fragment to PR #5271
MikeGoldsmith Jun 3, 2026
b6e4702
use ExemplarFilter for enum coercion test fixture; allow 'astroid' in…
MikeGoldsmith Jun 3, 2026
83e17bd
Merge branch 'mike/config-recursive-dict-conversion' into mike/config…
MikeGoldsmith Jun 3, 2026
52365e2
Merge branch 'mike/config-orchestrator' into mike/config-file-env-rou…
MikeGoldsmith Jun 3, 2026
3fc2669
fix lint on test_sdk.py: hoist import, disable no-self-use
MikeGoldsmith Jun 3, 2026
119bc83
Merge branch 'mike/config-orchestrator' into mike/config-file-env-rou…
MikeGoldsmith Jun 3, 2026
417d451
silence pylint/ruff on intentional lazy imports
MikeGoldsmith Jun 3, 2026
41667ca
remove extra blank line after imports (ruff I001)
MikeGoldsmith Jun 3, 2026
297da35
Merge branch 'mike/config-orchestrator' into mike/config-file-env-rou…
MikeGoldsmith Jun 3, 2026
2b2d47b
collapse multi-line @patch decorators (ruff format)
MikeGoldsmith Jun 3, 2026
f844bb6
add public opentelemetry.sdk.configuration namespace
MikeGoldsmith Jun 3, 2026
7ca840f
rename changelog fragment to PR #5276
MikeGoldsmith Jun 5, 2026
70c93d9
add end-to-end loader tests covering YAML -> typed config -> factory
MikeGoldsmith Jun 5, 2026
828c54b
Merge branch 'mike/config-recursive-dict-conversion' into mike/config…
MikeGoldsmith Jun 5, 2026
62cdfa4
Merge branch 'mike/config-orchestrator' into mike/config-file-env-rou…
MikeGoldsmith Jun 5, 2026
c85333d
Merge branch 'mike/config-file-env-routing' into mike/config-public-n…
MikeGoldsmith Jun 5, 2026
111fc4a
Merge branch 'main' into mike/config-file-env-routing
MikeGoldsmith Jun 9, 2026
e111ebf
Merge branch 'main' into mike/config-file-env-routing
MikeGoldsmith Jun 16, 2026
73982d9
address review feedback on OTEL_CONFIG_FILE routing
MikeGoldsmith Jun 16, 2026
df88a20
Merge branch 'main' into mike/config-file-env-routing
MikeGoldsmith Jun 17, 2026
4a41603
Merge branch 'main' into mike/config-file-env-routing
MikeGoldsmith Jun 17, 2026
4ce08db
tighten OTEL_CONFIG_FILE docstring (review feedback from herin049)
MikeGoldsmith Jun 19, 2026
054b729
Merge branch 'mike/config-file-env-routing' into mike/config-public-n…
MikeGoldsmith Jun 19, 2026
a967ece
Merge remote-tracking branch 'upstream/main' into mike/config-public-…
MikeGoldsmith Jun 19, 2026
dd08c91
Merge remote-tracking branch 'upstream/main' into mike/config-public-…
MikeGoldsmith Jun 24, 2026
a54c1cb
replace lazy __getattr__ with wrapper function (review feedback)
MikeGoldsmith Jun 24, 2026
23e32f2
Merge branch 'main' into mike/config-public-namespace
MikeGoldsmith Jun 24, 2026
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
1 change: 1 addition & 0 deletions .changelog/5276.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-sdk`: add public `opentelemetry.sdk.configuration` module that re-exports `configure_sdk`, `load_config_file`, `OpenTelemetryConfiguration`, and `ConfigurationError`. `load_config_file` is resolved lazily so the file-configuration extras (pyyaml, jsonschema) remain optional for callers that build an `OpenTelemetryConfiguration` programmatically.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

"""Public API for the OpenTelemetry SDK's declarative configuration.

Load a parsed configuration from a YAML/JSON file and apply it to the
process-global SDK providers:

>>> from opentelemetry.sdk.configuration import (
... load_config_file, configure_sdk,
... )
>>> config = load_config_file("otel-config.yaml")
>>> configure_sdk(config)

Construct a configuration programmatically and apply it:

>>> from opentelemetry.sdk.configuration import (
... OpenTelemetryConfiguration, configure_sdk,
... )
>>> configure_sdk(OpenTelemetryConfiguration(file_format="1.0-rc.1"))

Loading from a file requires the optional ``[file-configuration]`` extras
(``pyyaml`` and ``jsonschema``). ``configure_sdk`` itself has no extra
dependencies: callers that construct an ``OpenTelemetryConfiguration``
directly can use it without installing the extras.
"""

from __future__ import annotations

import os

from opentelemetry.sdk._configuration._exceptions import ConfigurationError
from opentelemetry.sdk._configuration._sdk import configure_sdk
from opentelemetry.sdk._configuration.models import OpenTelemetryConfiguration


def load_config_file(
file_path: str | os.PathLike[str],
) -> OpenTelemetryConfiguration:
"""Load and parse an OpenTelemetry configuration file.

Thin wrapper that defers importing the file loader until first call so
the optional ``[file-configuration]`` extras (``pyyaml``, ``jsonschema``)
are not required just to import this module. See
:func:`opentelemetry.sdk._configuration.file._loader.load_config_file`
for the full behaviour and error contract.
"""
# pylint: disable=import-outside-toplevel
from opentelemetry.sdk._configuration.file._loader import ( # noqa: PLC0415
load_config_file as _load_config_file,
)

return _load_config_file(file_path)


__all__ = [
"ConfigurationError",
"OpenTelemetryConfiguration",
"configure_sdk",
"load_config_file",
]
66 changes: 66 additions & 0 deletions opentelemetry-sdk/tests/_configuration/test_public_namespace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

# pylint: disable=protected-access

import os
import tempfile
import unittest

from opentelemetry.sdk import configuration
from opentelemetry.sdk._configuration._exceptions import ConfigurationError
from opentelemetry.sdk._configuration._sdk import configure_sdk
from opentelemetry.sdk._configuration.models import (
OpenTelemetryConfiguration,
)

_PUBLIC_NAMES = (
"ConfigurationError",
"OpenTelemetryConfiguration",
"configure_sdk",
"load_config_file",
)


class TestPublicNamespace(unittest.TestCase):
def test_public_symbols_resolve(self):
for name in _PUBLIC_NAMES:
self.assertTrue(
hasattr(configuration, name),
f"{name!r} missing from public namespace",
)

def test_public_symbols_match_private(self):
# Public namespace re-exports the same objects for the eager binds,
# not copies.
self.assertIs(configuration.ConfigurationError, ConfigurationError)
self.assertIs(
configuration.OpenTelemetryConfiguration,
OpenTelemetryConfiguration,
)
self.assertIs(configuration.configure_sdk, configure_sdk)

def test_load_config_file_delegates_to_loader(self):
# ``load_config_file`` is a thin wrapper that defers importing the
# file loader until first call (so the optional ``[file-configuration]``
# extras stay optional). Behaviourally it must round-trip a minimal
# valid file to an ``OpenTelemetryConfiguration``.
with tempfile.NamedTemporaryFile(
mode="w", suffix=".yaml", delete=False
) as fh:
fh.write('file_format: "1.0"\n')
path = fh.name
try:
result = configuration.load_config_file(path)
finally:
os.unlink(path)
self.assertIsInstance(result, OpenTelemetryConfiguration)
self.assertEqual(result.file_format, "1.0")

def test_unknown_attribute_raises(self):
with self.assertRaises(AttributeError):
# pylint: disable=no-member
_ = configuration.no_such_thing

def test_dunder_all_is_exhaustive(self):
self.assertEqual(sorted(configuration.__all__), list(_PUBLIC_NAMES))
Loading