textmap.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # Copyright The OpenTelemetry Authors
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import abc
  15. import typing
  16. from opentelemetry.context.context import Context
  17. CarrierT = typing.TypeVar("CarrierT")
  18. # pylint: disable=invalid-name
  19. CarrierValT = typing.Union[typing.List[str], str]
  20. class Getter(abc.ABC, typing.Generic[CarrierT]):
  21. """This class implements a Getter that enables extracting propagated
  22. fields from a carrier.
  23. """
  24. @abc.abstractmethod
  25. def get(
  26. self, carrier: CarrierT, key: str
  27. ) -> typing.Optional[typing.List[str]]:
  28. """Function that can retrieve zero
  29. or more values from the carrier. In the case that
  30. the value does not exist, returns None.
  31. Args:
  32. carrier: An object which contains values that are used to
  33. construct a Context.
  34. key: key of a field in carrier.
  35. Returns: first value of the propagation key or None if the key doesn't
  36. exist.
  37. """
  38. @abc.abstractmethod
  39. def keys(self, carrier: CarrierT) -> typing.List[str]:
  40. """Function that can retrieve all the keys in a carrier object.
  41. Args:
  42. carrier: An object which contains values that are
  43. used to construct a Context.
  44. Returns:
  45. list of keys from the carrier.
  46. """
  47. class Setter(abc.ABC, typing.Generic[CarrierT]):
  48. """This class implements a Setter that enables injecting propagated
  49. fields into a carrier.
  50. """
  51. @abc.abstractmethod
  52. def set(self, carrier: CarrierT, key: str, value: str) -> None:
  53. """Function that can set a value into a carrier""
  54. Args:
  55. carrier: An object which contains values that are used to
  56. construct a Context.
  57. key: key of a field in carrier.
  58. value: value for a field in carrier.
  59. """
  60. class DefaultGetter(Getter[typing.Mapping[str, CarrierValT]]):
  61. def get(
  62. self, carrier: typing.Mapping[str, CarrierValT], key: str
  63. ) -> typing.Optional[typing.List[str]]:
  64. """Getter implementation to retrieve a value from a dictionary.
  65. Args:
  66. carrier: dictionary in which to get value
  67. key: the key used to get the value
  68. Returns:
  69. A list with a single string with the value if it exists, else None.
  70. """
  71. val = carrier.get(key, None)
  72. if val is None:
  73. return None
  74. if isinstance(val, typing.Iterable) and not isinstance(val, str):
  75. return list(val)
  76. return [val]
  77. def keys(
  78. self, carrier: typing.Mapping[str, CarrierValT]
  79. ) -> typing.List[str]:
  80. """Keys implementation that returns all keys from a dictionary."""
  81. return list(carrier.keys())
  82. default_getter: Getter[CarrierT] = DefaultGetter() # type: ignore
  83. class DefaultSetter(Setter[typing.MutableMapping[str, CarrierValT]]):
  84. def set(
  85. self,
  86. carrier: typing.MutableMapping[str, CarrierValT],
  87. key: str,
  88. value: CarrierValT,
  89. ) -> None:
  90. """Setter implementation to set a value into a dictionary.
  91. Args:
  92. carrier: dictionary in which to set value
  93. key: the key used to set the value
  94. value: the value to set
  95. """
  96. carrier[key] = value
  97. default_setter: Setter[CarrierT] = DefaultSetter() # type: ignore
  98. class TextMapPropagator(abc.ABC):
  99. """This class provides an interface that enables extracting and injecting
  100. context into headers of HTTP requests. HTTP frameworks and clients
  101. can integrate with TextMapPropagator by providing the object containing the
  102. headers, and a getter and setter function for the extraction and
  103. injection of values, respectively.
  104. """
  105. @abc.abstractmethod
  106. def extract(
  107. self,
  108. carrier: CarrierT,
  109. context: typing.Optional[Context] = None,
  110. getter: Getter[CarrierT] = default_getter,
  111. ) -> Context:
  112. """Create a Context from values in the carrier.
  113. The extract function should retrieve values from the carrier
  114. object using getter, and use values to populate a
  115. Context value and return it.
  116. Args:
  117. getter: a function that can retrieve zero
  118. or more values from the carrier. In the case that
  119. the value does not exist, return an empty list.
  120. carrier: and object which contains values that are
  121. used to construct a Context. This object
  122. must be paired with an appropriate getter
  123. which understands how to extract a value from it.
  124. context: an optional Context to use. Defaults to root
  125. context if not set.
  126. Returns:
  127. A Context with configuration found in the carrier.
  128. """
  129. @abc.abstractmethod
  130. def inject(
  131. self,
  132. carrier: CarrierT,
  133. context: typing.Optional[Context] = None,
  134. setter: Setter[CarrierT] = default_setter,
  135. ) -> None:
  136. """Inject values from a Context into a carrier.
  137. inject enables the propagation of values into HTTP clients or
  138. other objects which perform an HTTP request. Implementations
  139. should use the `Setter` 's set method to set values on the
  140. carrier.
  141. Args:
  142. carrier: An object that a place to define HTTP headers.
  143. Should be paired with setter, which should
  144. know how to set header values on the carrier.
  145. context: an optional Context to use. Defaults to current
  146. context if not set.
  147. setter: An optional `Setter` object that can set values
  148. on the carrier.
  149. """
  150. @property
  151. @abc.abstractmethod
  152. def fields(self) -> typing.Set[str]:
  153. """
  154. Gets the fields set in the carrier by the `inject` method.
  155. If the carrier is reused, its fields that correspond with the ones
  156. present in this attribute should be deleted before calling `inject`.
  157. Returns:
  158. A set with the fields set in `inject`.
  159. """