184 lines
5.9 KiB
Python
184 lines
5.9 KiB
Python
# Copyright The OpenTelemetry Authors
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
import abc
|
|
import typing
|
|
from collections.abc import Iterable, Mapping, MutableMapping
|
|
|
|
from opentelemetry.context.context import Context
|
|
|
|
CarrierT = typing.TypeVar("CarrierT")
|
|
# pylint: disable=invalid-name
|
|
CarrierValT = list[str] | str
|
|
|
|
|
|
class Getter(abc.ABC, typing.Generic[CarrierT]):
|
|
"""This class implements a Getter that enables extracting propagated
|
|
fields from a carrier.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def get(self, carrier: CarrierT, key: str) -> list[str] | None:
|
|
"""Function that can retrieve zero
|
|
or more values from the carrier. In the case that
|
|
the value does not exist, returns None.
|
|
|
|
Args:
|
|
carrier: An object which contains values that are used to
|
|
construct a Context.
|
|
key: key of a field in carrier.
|
|
Returns: first value of the propagation key or None if the key doesn't
|
|
exist.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def keys(self, carrier: CarrierT) -> list[str]:
|
|
"""Function that can retrieve all the keys in a carrier object.
|
|
|
|
Args:
|
|
carrier: An object which contains values that are
|
|
used to construct a Context.
|
|
Returns:
|
|
list of keys from the carrier.
|
|
"""
|
|
|
|
|
|
class Setter(abc.ABC, typing.Generic[CarrierT]):
|
|
"""This class implements a Setter that enables injecting propagated
|
|
fields into a carrier.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def set(self, carrier: CarrierT, key: str, value: str) -> None:
|
|
"""Function that can set a value into a carrier""
|
|
|
|
Args:
|
|
carrier: An object which contains values that are used to
|
|
construct a Context.
|
|
key: key of a field in carrier.
|
|
value: value for a field in carrier.
|
|
"""
|
|
|
|
|
|
class DefaultGetter(Getter[Mapping[str, CarrierValT]]):
|
|
def get(
|
|
self, carrier: Mapping[str, CarrierValT], key: str
|
|
) -> list[str] | None:
|
|
"""Getter implementation to retrieve a value from a dictionary.
|
|
|
|
Args:
|
|
carrier: dictionary in which to get value
|
|
key: the key used to get the value
|
|
Returns:
|
|
A list with a single string with the value if it exists, else None.
|
|
"""
|
|
val = carrier.get(key, None)
|
|
if val is None:
|
|
return None
|
|
if isinstance(val, Iterable) and not isinstance(val, str):
|
|
return list(val)
|
|
return [val]
|
|
|
|
def keys(self, carrier: Mapping[str, CarrierValT]) -> list[str]:
|
|
"""Keys implementation that returns all keys from a dictionary."""
|
|
return list(carrier.keys())
|
|
|
|
|
|
default_getter: Getter[CarrierT] = DefaultGetter() # type: ignore
|
|
|
|
|
|
class DefaultSetter(Setter[MutableMapping[str, CarrierValT]]):
|
|
def set(
|
|
self,
|
|
carrier: MutableMapping[str, CarrierValT],
|
|
key: str,
|
|
value: CarrierValT,
|
|
) -> None:
|
|
"""Setter implementation to set a value into a dictionary.
|
|
|
|
Args:
|
|
carrier: dictionary in which to set value
|
|
key: the key used to set the value
|
|
value: the value to set
|
|
"""
|
|
carrier[key] = value
|
|
|
|
|
|
default_setter: Setter[CarrierT] = DefaultSetter() # type: ignore
|
|
|
|
|
|
class TextMapPropagator(abc.ABC):
|
|
"""This class provides an interface that enables extracting and injecting
|
|
context into headers of HTTP requests. HTTP frameworks and clients
|
|
can integrate with TextMapPropagator by providing the object containing the
|
|
headers, and a getter and setter function for the extraction and
|
|
injection of values, respectively.
|
|
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def extract(
|
|
self,
|
|
carrier: CarrierT,
|
|
context: Context | None = None,
|
|
getter: Getter[CarrierT] = default_getter,
|
|
) -> Context:
|
|
"""Create a Context from values in the carrier.
|
|
|
|
The extract function should retrieve values from the carrier
|
|
object using getter, and use values to populate a
|
|
Context value and return it.
|
|
|
|
Args:
|
|
getter: a function that can retrieve zero
|
|
or more values from the carrier. In the case that
|
|
the value does not exist, return an empty list.
|
|
carrier: and object which contains values that are
|
|
used to construct a Context. This object
|
|
must be paired with an appropriate getter
|
|
which understands how to extract a value from it.
|
|
context: an optional Context to use. Defaults to root
|
|
context if not set.
|
|
Returns:
|
|
A Context with configuration found in the carrier.
|
|
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def inject(
|
|
self,
|
|
carrier: CarrierT,
|
|
context: Context | None = None,
|
|
setter: Setter[CarrierT] = default_setter,
|
|
) -> None:
|
|
"""Inject values from a Context into a carrier.
|
|
|
|
inject enables the propagation of values into HTTP clients or
|
|
other objects which perform an HTTP request. Implementations
|
|
should use the `Setter` 's set method to set values on the
|
|
carrier.
|
|
|
|
Args:
|
|
carrier: An object that a place to define HTTP headers.
|
|
Should be paired with setter, which should
|
|
know how to set header values on the carrier.
|
|
context: an optional Context to use. Defaults to current
|
|
context if not set.
|
|
setter: An optional `Setter` object that can set values
|
|
on the carrier.
|
|
|
|
"""
|
|
|
|
@property
|
|
@abc.abstractmethod
|
|
def fields(self) -> set[str]:
|
|
"""
|
|
Gets the fields set in the carrier by the `inject` method.
|
|
|
|
If the carrier is reused, its fields that correspond with the ones
|
|
present in this attribute should be deleted before calling `inject`.
|
|
|
|
Returns:
|
|
A set with the fields set in `inject`.
|
|
"""
|