_envcarrier.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # Copyright The OpenTelemetry Authors
  2. # SPDX-License-Identifier: Apache-2.0
  3. """Environment variable carriers for text map propagators.
  4. Use :class:`EnvironmentGetter` with the environment mapping to extract from,
  5. usually ``os.environ`` during application or child-process initialization.
  6. Use :class:`EnvironmentSetter` with a mutable environment copy when preparing
  7. the environment for a child process.
  8. """
  9. import re
  10. from collections.abc import Mapping, MutableMapping
  11. from opentelemetry.propagators.textmap import Getter, Setter
  12. def _normalize_key(key: str) -> str:
  13. if not key:
  14. return "_"
  15. result = re.sub(r"[^A-Za-z0-9_]", "_", key).upper()
  16. if result and result[0].isdigit():
  17. result = "_" + result
  18. return result
  19. def _is_normalized_key(key: str) -> bool:
  20. if not key:
  21. return False
  22. if "0" <= key[0] <= "9":
  23. return False
  24. return all(
  25. "A" <= char <= "Z" or "0" <= char <= "9" or char == "_" for char in key
  26. )
  27. class EnvironmentGetter(Getter[Mapping[str, str]]):
  28. """Getter implementation for extracting context and baggage from environment variables.
  29. EnvironmentGetter reads from the mapping provided as the carrier, normalizes
  30. requested keys, and provides simple data access without validation.
  31. Example usage:
  32. getter = EnvironmentGetter()
  33. traceparent = getter.get(os.environ, "traceparent")
  34. """
  35. def get(self, carrier: Mapping[str, str], key: str) -> list[str] | None:
  36. """Get a value from the environment carrier for the given key.
  37. Args:
  38. carrier: Mapping to read environment variables from
  39. key: The key to look up (will be normalized)
  40. Returns:
  41. A list with a single string value if the key exists, None otherwise.
  42. """
  43. val = carrier.get(_normalize_key(key))
  44. if val is None:
  45. return None
  46. return [val]
  47. def keys(self, carrier: Mapping[str, str]) -> list[str]:
  48. """Get all keys from the environment carrier.
  49. Args:
  50. carrier: Mapping to read environment variable keys from
  51. Returns:
  52. List of all already-normalized environment variable keys.
  53. """
  54. return [key for key in carrier.keys() if _is_normalized_key(key)]
  55. class EnvironmentSetter(Setter[MutableMapping[str, str]]):
  56. """Setter implementation for building environment variable dictionaries.
  57. EnvironmentSetter builds a dictionary of environment variables that
  58. can be passed to utilities like subprocess.run()
  59. Example usage:
  60. setter = EnvironmentSetter()
  61. env_vars = {}
  62. setter.set(env_vars, "traceparent", "00-trace-id-span-id-01")
  63. subprocess.run(myCommand, env=env_vars)
  64. """
  65. def set(
  66. self, carrier: MutableMapping[str, str], key: str, value: str
  67. ) -> None:
  68. """Set a value in the carrier dictionary for the given key.
  69. Args:
  70. carrier: Dictionary to store environment variables
  71. key: The key to set (normalized)
  72. value: The value to set
  73. """
  74. carrier[_normalize_key(key)] = value