Skip to content

feat(config): add configure_sdk orchestrator for declarative config#5270

Draft
MikeGoldsmith wants to merge 11 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/config-orchestrator
Draft

feat(config): add configure_sdk orchestrator for declarative config#5270
MikeGoldsmith wants to merge 11 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/config-orchestrator

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

@MikeGoldsmith MikeGoldsmith commented Jun 3, 2026

Description

Adds configure_sdk(config) — a single entry point that takes a parsed OpenTelemetryConfiguration and applies it by:

  1. Honoring the top-level disabled flag (no-op when true)
  2. Building the resource via create_resource
  3. Calling configure_tracer_provider, configure_meter_provider, configure_logger_provider, and configure_propagator in order

This is the first slice of #5126 — wiring the existing per-signal factories into one orchestrator. Env-var-to-config adapter and unification with _initialize_components are deferred to follow-up PRs.

from opentelemetry.sdk._configuration.file import load_config_file, configure_sdk

config = load_config_file("otel-config.yaml")
configure_sdk(config)

Refs #3631
Refs #5126

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

5 new tests in tests/_configuration/test_sdk.py:

  • All four signal configure_* calls receive the correct (config, resource) pair
  • disabled=true skips every call including create_resource
  • disabled=false runs normal setup
  • Absent sections (tracer_provider=None etc.) still pass None through to each configure_*
  • Integration: configure_sdk with a real TracerProviderConfig triggers trace.set_tracer_provider with an SDK TracerProvider

Does This PR Require a Contrib Repo Change?

  • Yes.
  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

Note

This PR is stacked on top of #5269 (recursive dict-to-dataclass conversion in the loader). The diff includes #5269's changes until that PR lands; rebase will clean it up. The transient changelog failure (validator flags 5269.added as added on this PR) also resolves on #5269 merging.

Adds `_dict_to_dataclass` in `_conversion.py` which walks each field's
type annotation and converts:
- nested dicts → typed dataclass instances
- lists of dicts → lists of typed dataclasses
- string/value → Enum members (e.g. log_level: info)
- unknown keys → routed to the @_additional_properties decorator

The loader's `_dict_to_model` now produces a fully-typed
OpenTelemetryConfiguration tree end-to-end. Factory functions can rely
on typed attribute access (config.tracer_provider.processors[0].batch
.exporter.otlp_http.endpoint) instead of failing on raw dicts.

This closes the gap between load_config_file() and the factory
functions — YAML/JSON config → SDK objects now works end-to-end.

Closes open-telemetry#5127

Assisted-by: Claude Opus 4.6
- Use TypeVar for _dict_to_dataclass return — callers now get the
  correct type instead of Any
- Use collections.abc.Mapping for input (more permissive than dict)
- Add explicit is_dataclass check at entry — raises TypeError with a
  descriptive message instead of failing later in dataclasses.fields

Assisted-by: Claude Opus 4.6
Astroid 3.x (used by pylint 3.x) follows typing.get_type_hints into
Python 3.14's annotationlib, which contains t-string literals it can't
parse and crashes with AttributeError on 'visit_templatestr'. Wrapping
the call in a helper that returns dict[str, Any] stops the inference at
the declared return type.

Assisted-by: Claude Opus 4.7
Same effect as the prior helper — declaring the local as ``dict[str, Any]``
stops astroid's inference at the annotation rather than tracing into the
typing internals.

Assisted-by: Claude Opus 4.7
Single entry point that takes a parsed OpenTelemetryConfiguration,
builds the resource, and applies the tracer/meter/logger providers
and propagator globally. Honors the top-level disabled flag — when
true, no globals are touched.

The orchestrator is a thin composition of the existing per-signal
configure_* factories; the deeper unification with the env-var path
(see open-telemetry#5126) is left for follow-up.

Refs open-telemetry#3631
Refs open-telemetry#5126

Assisted-by: Claude Opus 4.7
@MikeGoldsmith MikeGoldsmith requested a review from a team as a code owner June 3, 2026 11:41
… codespell

Replace the bespoke _Level enum (which violated pylint's invalid-name on
lowercase members) with the real ExemplarFilter enum from models.py — the
generated models use lowercase values verbatim from the JSON schema, so
using one of them avoids fighting the linter and exercises the same code
path with real data shapes.

Add 'astroid' to codespell's ignore-words-list; the prior commit's
explanatory comment mentions the library by name and codespell flagged it
as a misspelling of 'asteroid'.

Assisted-by: Claude Opus 4.7
Move ``SdkTracerProvider`` import to module top (ruff PLC0415 /
pylint C0415) and add explicit ``# pylint: disable=no-self-use``
on the three mock-only tests that intentionally do not touch
``self``.

Assisted-by: Claude Opus 4.7
@MikeGoldsmith MikeGoldsmith marked this pull request as draft June 3, 2026 14:29
@MikeGoldsmith MikeGoldsmith moved this to Ready for review in Python PR digest Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

1 participant