Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e5c70a2
api: conditionally load entrypoints for OTEL_PYTHON_CONTEXT
codeboten Apr 24, 2026
4024ef7
add ignore rule to import lint, update changelog
codeboten Apr 27, 2026
2861d76
fix precommit
codeboten Apr 27, 2026
460af4d
clean up changelog
codeboten Apr 27, 2026
7d2e1c6
Merge branch 'main' into codeboten/load-context-api
codeboten Apr 29, 2026
c0411a2
Merge branch 'main' into codeboten/load-context-api
codeboten Apr 30, 2026
6099eee
Merge branch 'main' into codeboten/load-context-api
codeboten May 5, 2026
91c3996
Merge branch 'main' into codeboten/load-context-api
codeboten May 5, 2026
c50a2fd
Merge branch 'main' into codeboten/load-context-api
MikeGoldsmith May 7, 2026
6750d11
Merge branch 'main' into codeboten/load-context-api
codeboten May 7, 2026
76c5580
Merge branch 'main' into codeboten/load-context-api
MikeGoldsmith May 11, 2026
bd6ae52
Merge branch 'main' into codeboten/load-context-api
codeboten May 11, 2026
d0de9e8
Merge branch 'main' into codeboten/load-context-api
codeboten May 11, 2026
c1bf486
Merge branch 'main' into codeboten/load-context-api
codeboten May 12, 2026
4744de1
Merge branch 'main' into codeboten/load-context-api
codeboten May 13, 2026
9152c35
use changelog fragment
codeboten May 14, 2026
2a66974
Merge branch 'main' into codeboten/load-context-api
codeboten May 14, 2026
6bb9251
Merge branch 'main' into codeboten/load-context-api
codeboten May 14, 2026
9d8e230
Merge branch 'main' into codeboten/load-context-api
codeboten May 19, 2026
aba0170
apply the same pattern to propagators and providers
codeboten May 19, 2026
7affb49
precommit
codeboten May 20, 2026
ab54873
Potential fix for pull request finding
codeboten May 20, 2026
8879126
put public symbols back
codeboten May 20, 2026
861cf10
rename vars
codeboten May 20, 2026
bbabf36
Merge branch 'main' into codeboten/load-context-api
codeboten May 20, 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/5144.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-api`: conditionally import entrypoints for `opentelemetry_context` only if the `OTEL_PYTHON_CONTEXT` env variable is defined, return `ContextVarsRuntimeContext` otherwise
38 changes: 15 additions & 23 deletions opentelemetry-api/src/opentelemetry/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from __future__ import annotations

import logging
import os
from contextvars import Token
from os import environ
from uuid import uuid4

# pylint: disable=wrong-import-position
from opentelemetry.context.context import Context, _RuntimeContext # noqa
from opentelemetry.context.contextvars_context import ContextVarsRuntimeContext
from opentelemetry.environment_variables import OTEL_PYTHON_CONTEXT
from opentelemetry.util._importlib_metadata import entry_points

logger = logging.getLogger(__name__)

Expand All @@ -22,37 +22,29 @@ def _load_runtime_context() -> _RuntimeContext:
Returns:
An instance of RuntimeContext.
"""
configured_context = os.environ.get(OTEL_PYTHON_CONTEXT)
if not configured_context:
return ContextVarsRuntimeContext()

# FIXME use a better implementation of a configuration manager
# to avoid having to get configuration values straight from
# environment variables
default_context = "contextvars_context"

configured_context = environ.get(OTEL_PYTHON_CONTEXT, default_context) # type: str
Comment thread
aabmass marked this conversation as resolved.
# pylint: disable=import-outside-toplevel,no-name-in-module
from opentelemetry.util._importlib_metadata import ( # noqa: PLC0415
entry_points,
)

try:
return next( # type: ignore
iter( # type: ignore
entry_points( # type: ignore
group="opentelemetry_context",
name=configured_context,
return next(
iter(
entry_points(
group="opentelemetry_context", name=configured_context
)
)
).load()()
Comment thread
codeboten marked this conversation as resolved.
except Exception: # pylint: disable=broad-exception-caught
logger.exception(
"Failed to load context: %s, fallback to %s",
"Failed to load context: %s, falling back to contextvars_context",
configured_context,
default_context,
)
return next( # type: ignore
iter( # type: ignore
entry_points( # type: ignore
group="opentelemetry_context",
name=default_context,
)
)
).load()()
return ContextVarsRuntimeContext()


_RUNTIME_CONTEXT = _load_runtime_context()
Expand Down
89 changes: 54 additions & 35 deletions opentelemetry-api/src/opentelemetry/propagate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def example_route():
from opentelemetry.context.context import Context
from opentelemetry.environment_variables import OTEL_PROPAGATORS
from opentelemetry.propagators import composite, textmap
from opentelemetry.util._importlib_metadata import entry_points

logger = getLogger(__name__)

Expand Down Expand Up @@ -109,46 +108,66 @@ def inject(
get_global_textmap().inject(carrier, context=context, setter=setter)


propagators: list[textmap.TextMapPropagator] = []

# Single use variable here to hack black and make lint pass
environ_propagators = environ.get(
OTEL_PROPAGATORS,
"tracecontext,baggage",
)
def _load_propagators() -> textmap.TextMapPropagator:
configured = environ.get(OTEL_PROPAGATORS)
if not configured:
# pylint: disable=import-outside-toplevel,no-name-in-module
from opentelemetry.baggage.propagation import ( # noqa: PLC0415
W3CBaggagePropagator,
)

# pylint: disable=import-outside-toplevel,no-name-in-module
from opentelemetry.trace.propagation.tracecontext import ( # noqa: PLC0415
TraceContextTextMapPropagator,
)

for propagator in environ_propagators.split(","):
propagator = propagator.strip()
if propagator.lower() == "none":
logger.debug(
"OTEL_PROPAGATORS environment variable contains none, removing all propagators"
return composite.CompositePropagator(
[TraceContextTextMapPropagator(), W3CBaggagePropagator()]
)
propagators = []
break
try:
propagators.append(
next( # type: ignore
iter( # type: ignore
entry_points( # type: ignore[misc]
group="opentelemetry_propagator",
name=propagator,

# pylint: disable=import-outside-toplevel,no-name-in-module
from opentelemetry.util._importlib_metadata import ( # noqa: PLC0415
entry_points,
)

_propagators: list[textmap.TextMapPropagator] = []
for _propagator in configured.split(","):
_propagator = _propagator.strip()
if _propagator.lower() == "none":
logger.debug(
"OTEL_PROPAGATORS environment variable contains none, removing all propagators"
)
return composite.CompositePropagator([])
Comment thread
codeboten marked this conversation as resolved.
try:
_propagators.append(
next( # type: ignore
iter( # type: ignore
entry_points( # type: ignore[misc]
group="opentelemetry_propagator",
name=_propagator,
)
)
)
).load()()
)
except StopIteration:
raise ValueError(
f"Propagator {propagator} not found. It is either misspelled or not installed."
)
except Exception: # pylint: disable=broad-exception-caught
logger.exception("Failed to load propagator: %s", propagator)
raise
).load()()
)
except StopIteration:
raise ValueError(
f"Propagator {_propagator} not found. It is either misspelled or not installed."
)
except Exception: # pylint: disable=broad-exception-caught
logger.exception("Failed to load propagator: %s", _propagator)
raise
return composite.CompositePropagator(_propagators)


_HTTP_TEXT_FORMAT: textmap.TextMapPropagator = _load_propagators()

# Deprecated: propagators, environ_propagators and propagator names were never intendended to be part of the public API.
propagators: list[textmap.TextMapPropagator] = []

environ_propagators = environ.get(OTEL_PROPAGATORS, "tracecontext,baggage")

_HTTP_TEXT_FORMAT: textmap.TextMapPropagator = composite.CompositePropagator(
propagators
)
for propagator in environ_propagators.split(","): # type: ignore[assignment]
propagator = propagator.strip()


def get_global_textmap() -> textmap.TextMapPropagator:
Expand Down
7 changes: 5 additions & 2 deletions opentelemetry-api/src/opentelemetry/util/_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
from os import environ
from typing import TYPE_CHECKING, TypeVar, cast

from opentelemetry.util._importlib_metadata import entry_points

if TYPE_CHECKING:
from opentelemetry.metrics import MeterProvider
from opentelemetry.trace import TracerProvider
Expand All @@ -19,6 +17,11 @@
def _load_provider(
provider_environment_variable: str, provider: str
) -> Provider: # type: ignore[type-var]
# pylint: disable=import-outside-toplevel,no-name-in-module
Comment thread
aabmass marked this conversation as resolved.
from opentelemetry.util._importlib_metadata import ( # noqa: PLC0415
entry_points,
)

try:
provider_name = cast(
str,
Expand Down
Loading